# HG changeset patch # User rfield # Date 1382486001 25200 # Node ID 6cd16d8ed2b987d6c79781e8dff0f37d0d841300 # Parent 963c57175e40b210dbd90e1aff54fa230448577e 8023668: Desugar serializable lambda bodies using more robust naming scheme Summary: lambda / bridged method-reference naming overhaul Reviewed-by: ksrini, briangoetz diff -r 963c57175e40 -r 6cd16d8ed2b9 src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Oct 22 13:54:49 2013 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Oct 22 16:53:21 2013 -0700 @@ -30,7 +30,6 @@ import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeTranslator; import com.sun.tools.javac.code.Attribute; -import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Symbol; @@ -576,10 +575,10 @@ DiagnosticPosition pos, List staticArgs, MethodType indyType) { String functionalInterfaceClass = classSig(targetType); String functionalInterfaceMethodName = samSym.getSimpleName().toString(); - String functionalInterfaceMethodSignature = methodSig(types.erasure(samSym.type)); + String functionalInterfaceMethodSignature = typeSig(types.erasure(samSym.type)); String implClass = classSig(types.erasure(refSym.owner.type)); String implMethodName = refSym.getQualifiedName().toString(); - String implMethodSignature = methodSig(types.erasure(refSym.type)); + String implMethodSignature = typeSig(types.erasure(refSym.type)); JCExpression kindTest = eqTest(syms.intType, deserGetter("getImplMethodKind", syms.intType), make.Literal(implMethodKind)); ListBuffer serArgs = new ListBuffer<>(); @@ -1087,8 +1086,21 @@ * keep the count of lambda expression defined in given context (used to * generate unambiguous names for serializable lambdas) */ - private Map serializableLambdaCounts = - new HashMap(); + private class SyntheticMethodNameCounter { + private Map map = new HashMap<>(); + int getIndex(StringBuilder buf) { + String temp = buf.toString(); + Integer count = map.get(temp); + if (count == null) { + count = 0; + } + ++count; + map.put(temp, count); + return count; + } + } + private SyntheticMethodNameCounter syntheticMethodNameCounts = + new SyntheticMethodNameCounter(); private Map localClassDefs; @@ -1122,13 +1134,13 @@ @Override public void visitClassDef(JCClassDecl tree) { List prevStack = frameStack; - Map prevSerializableLambdaCount = - serializableLambdaCounts; + SyntheticMethodNameCounter prevSyntheticMethodNameCounts = + syntheticMethodNameCounts; Map prevClinits = clinits; DiagnosticSource prevSource = log.currentSource(); try { log.useSource(tree.sym.sourcefile); - serializableLambdaCounts = new HashMap(); + syntheticMethodNameCounts = new SyntheticMethodNameCounter(); prevClinits = new HashMap(); if (tree.sym.owner.kind == MTH) { localClassDefs.put(tree.sym, tree); @@ -1154,7 +1166,7 @@ finally { log.useSource(prevSource.getFile()); frameStack = prevStack; - serializableLambdaCounts = prevSerializableLambdaCount; + syntheticMethodNameCounts = prevSyntheticMethodNameCounts; clinits = prevClinits; } } @@ -1379,50 +1391,6 @@ } } - private Name lambdaName() { - return names.lambda.append(names.fromString("" + lambdaCount++)); - } - - /** - * For a serializable lambda, generate a name which maximizes name - * stability across deserialization. - * @param owner - * @return Name to use for the synthetic lambda method name - */ - private Name serializedLambdaName(Symbol owner) { - StringBuilder buf = new StringBuilder(); - buf.append(names.lambda); - // Append the name of the method enclosing the lambda. - String methodName = owner.name.toString(); - if (methodName.equals("")) - methodName = "static"; - else if (methodName.equals("")) - methodName = "new"; - buf.append(methodName); - buf.append('$'); - // Append a hash of the enclosing method signature to differentiate - // overloaded enclosing methods. For lambdas enclosed in lambdas, - // the generated lambda method will not have type yet, but the - // enclosing method's name will have been generated with this same - // method, so it will be unique and never be overloaded. - Assert.check(owner.type != null || directlyEnclosingLambda() != null); - if (owner.type != null) { - int methTypeHash = methodSig(owner.type).hashCode(); - buf.append(Integer.toHexString(methTypeHash)); - } - buf.append('$'); - // The above appended name components may not be unique, append a - // count based on the above name components. - String temp = buf.toString(); - Integer count = serializableLambdaCounts.get(temp); - if (count == null) { - count = 0; - } - buf.append(count++); - serializableLambdaCounts.put(temp, count); - return names.fromString(buf.toString()); - } - /** * Return a valid owner given the current declaration stack * (required to skip synthetic lambda symbols) @@ -1639,19 +1607,19 @@ private abstract class TranslationContext { /** the underlying (untranslated) tree */ - T tree; + final T tree; /** points to the adjusted enclosing scope in which this lambda/mref expression occurs */ - Symbol owner; + final Symbol owner; /** the depth of this lambda expression in the frame stack */ - int depth; + final int depth; /** the enclosing translation context (set for nested lambdas/mref) */ - TranslationContext prev; + final TranslationContext prev; /** list of methods to be bridged by the meta-factory */ - List bridges; + final List bridges; TranslationContext(T tree) { this.tree = tree; @@ -1679,6 +1647,31 @@ } return false; } + + /** + * @return Name of the enclosing method to be folded into synthetic + * method name + */ + String enclosingMethodName() { + return syntheticMethodNameComponent(owner.name); + } + + /** + * @return Method name in a form that can be folded into a + * component of a synthetic method name + */ + String syntheticMethodNameComponent(Name name) { + if (name == null) { + return "null"; + } + String methodName = name.toString(); + if (methodName.equals("")) { + methodName = "static"; + } else if (methodName.equals("")) { + methodName = "new"; + } + return methodName; + } } /** @@ -1690,7 +1683,10 @@ private class LambdaTranslationContext extends TranslationContext { /** variable in the enclosing context to which this lambda is assigned */ - Symbol self; + final Symbol self; + + /** variable in the enclosing context to which this lambda is assigned */ + final Symbol assignedTo; Map> translatedSymbols; @@ -1702,11 +1698,22 @@ LambdaTranslationContext(JCLambda tree) { super(tree); Frame frame = frameStack.head; - if (frame.tree.hasTag(VARDEF)) { - self = ((JCVariableDecl)frame.tree).sym; - } - Name name = isSerializable() ? serializedLambdaName(owner) : lambdaName(); - this.translatedSym = makePrivateSyntheticMethod(0, name, null, owner.enclClass()); + switch (frame.tree.getTag()) { + case VARDEF: + assignedTo = self = ((JCVariableDecl) frame.tree).sym; + break; + case ASSIGN: + self = null; + assignedTo = TreeInfo.symbol(((JCAssign) frame.tree).getVariable()); + break; + default: + assignedTo = self = null; + break; + } + + // This symbol will be filled-in in complete + this.translatedSym = makePrivateSyntheticMethod(0, null, null, owner.enclClass()); + if (dumpLambdaToMethodStats) { log.note(tree, "lambda.stat", needsAltMetafactory(), translatedSym); } @@ -1719,6 +1726,84 @@ translatedSymbols.put(TYPE_VAR, new LinkedHashMap()); } + /** + * For a serializable lambda, generate a disambiguating string + * which maximizes stability across deserialization. + * + * @return String to differentiate synthetic lambda method names + */ + private String serializedLambdaDisambiguation() { + StringBuilder buf = new StringBuilder(); + // Append the enclosing method signature to differentiate + // overloaded enclosing methods. For lambdas enclosed in + // lambdas, the generated lambda method will not have type yet, + // but the enclosing method's name will have been generated + // with this same method, so it will be unique and never be + // overloaded. + Assert.check( + owner.type != null || + directlyEnclosingLambda() != null); + if (owner.type != null) { + buf.append(typeSig(owner.type)); + buf.append(":"); + } + + // Add target type info + buf.append(types.findDescriptorSymbol(tree.type.tsym).owner.flatName()); + buf.append(" "); + + // Add variable assigned to + if (assignedTo != null) { + buf.append(assignedTo.flatName()); + buf.append("="); + } + //add captured locals info: type, name, order + for (Symbol fv : getSymbolMap(CAPTURED_VAR).keySet()) { + if (fv != self) { + buf.append(typeSig(fv.type)); + buf.append(" "); + buf.append(fv.flatName()); + buf.append(","); + } + } + + return buf.toString(); + } + + /** + * For a non-serializable lambda, generate a simple method. + * + * @return Name to use for the synthetic lambda method name + */ + private Name lambdaName() { + return names.lambda.append(names.fromString(enclosingMethodName() + "$" + lambdaCount++)); + } + + /** + * For a serializable lambda, generate a method name which maximizes + * name stability across deserialization. + * + * @return Name to use for the synthetic lambda method name + */ + private Name serializedLambdaName() { + StringBuilder buf = new StringBuilder(); + buf.append(names.lambda); + // Append the name of the method enclosing the lambda. + buf.append(enclosingMethodName()); + buf.append('$'); + // Append a hash of the disambiguating string : enclosing method + // signature, etc. + String disam = serializedLambdaDisambiguation(); + buf.append(Integer.toHexString(disam.hashCode())); + buf.append('$'); + // The above appended name components may not be unique, append + // a count based on the above name components. + buf.append(syntheticMethodNameCounts.getIndex(buf)); + String result = buf.toString(); + //System.err.printf("serializedLambdaName: %s -- %s\n", result, disam); + return names.fromString(result); + } + /** * Translate a symbol of a given kind into something suitable for the * synthetic lambda body @@ -1847,6 +1932,11 @@ } syntheticParams = params.toList(); + // Compute and set the lambda name + translatedSym.name = isSerializable() + ? serializedLambdaName() + : lambdaName(); + //prepend synthetic args to translated lambda method signature translatedSym.type = types.createMethodTypeWithParameters( generatedLambdaSig(), @@ -1874,7 +1964,7 @@ this.isSuper = tree.hasKind(ReferenceKind.SUPER); this.bridgeSym = needsBridge() ? makePrivateSyntheticMethod(isSuper ? 0 : STATIC, - lambdaName().append(names.fromString("$bridge")), null, + referenceBridgeName(), null, owner.enclClass()) : null; if (dumpLambdaToMethodStats) { @@ -1888,7 +1978,9 @@ * Get the opcode associated with this method reference */ int referenceKind() { - return LambdaToMethod.this.referenceKind(needsBridge() ? bridgeSym : tree.sym); + return LambdaToMethod.this.referenceKind(needsBridge() + ? bridgeSym + : tree.sym); } boolean needsVarArgsConversion() { @@ -1896,6 +1988,62 @@ } /** + * Generate a disambiguating string to increase stability (important + * if serialized) + * + * @return String to differentiate synthetic lambda method names + */ + private String referenceBridgeDisambiguation() { + StringBuilder buf = new StringBuilder(); + // Append the enclosing method signature to differentiate + // overloaded enclosing methods. + if (owner.type != null) { + buf.append(typeSig(owner.type)); + buf.append(":"); + } + + // Append qualifier type + buf.append(classSig(tree.sym.owner.type)); + + // Note static/instance + buf.append(tree.sym.isStatic()? " S " : " I "); + + // Append referenced signature + buf.append(typeSig(tree.sym.erasure(types))); + + return buf.toString(); + } + + /** + * Construct a unique stable name for the method reference bridge + * + * @return Name to use for the synthetic method name + */ + private Name referenceBridgeName() { + StringBuilder buf = new StringBuilder(); + // Append lambda ID, this is semantically significant + buf.append(names.lambda); + // Note that it is a method reference bridge + buf.append("MR$"); + // Append the enclosing method name + buf.append(enclosingMethodName()); + buf.append('$'); + // Append the referenced method name + buf.append(syntheticMethodNameComponent(tree.sym.name)); + buf.append('$'); + // Append a hash of the disambiguating string : enclosing method + // signature, etc. + String disam = referenceBridgeDisambiguation(); + buf.append(Integer.toHexString(disam.hashCode())); + buf.append('$'); + // The above appended name components may not be unique, append + // a count based on the above name components. + buf.append(syntheticMethodNameCounts.getIndex(buf)); + String result = buf.toString(); + return names.fromString(result); + } + + /** * @return Is this an array operation like clone() */ boolean isArrayOp() { @@ -1954,7 +2102,7 @@ * **************************************************************** */ - private String methodSig(Type type) { + private String typeSig(Type type) { L2MSignatureGenerator sg = new L2MSignatureGenerator(); sg.assembleSig(type); return sg.toString(); diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/MethodParameters/LambdaTest.out --- a/test/tools/javac/MethodParameters/LambdaTest.out Tue Oct 22 13:54:49 2013 +0100 +++ b/test/tools/javac/MethodParameters/LambdaTest.out Tue Oct 22 16:53:21 2013 -0700 @@ -1,7 +1,7 @@ class LambdaTest -- LambdaTest.() LambdaTest.foo(i) -LambdaTest.lambda$1(arg0, arg1)/*synthetic*/ -LambdaTest.lambda$0(arg0)/*synthetic*/ +LambdaTest.lambda$static$1(arg0)/*synthetic*/ +LambdaTest.lambda$null$0(arg0, arg1)/*synthetic*/ static interface LambdaTest$I -- inner -LambdaTest$I.m(x) \ No newline at end of file +LambdaTest$I.m(x) diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/T8019486/WrongLVTForLambdaTest.java --- a/test/tools/javac/T8019486/WrongLVTForLambdaTest.java Tue Oct 22 13:54:49 2013 +0100 +++ b/test/tools/javac/T8019486/WrongLVTForLambdaTest.java Tue Oct 22 16:53:21 2013 -0700 @@ -61,8 +61,6 @@ {9, 0}, //number -> number / 1 }; - static final String methodToLookFor = "lambda$0"; - public static void main(String[] args) throws Exception { new WrongLVTForLambdaTest().run(); } @@ -70,7 +68,7 @@ void run() throws Exception { compileTestClass(); checkClassFile(new File(Paths.get(System.getProperty("user.dir"), - "Foo.class").toUri()), methodToLookFor); + "Foo.class").toUri())); } void compileTestClass() throws Exception { @@ -79,12 +77,12 @@ ToolBox.javac(javacSuccessArgs); } - void checkClassFile(final File cfile, String methodToFind) throws Exception { + void checkClassFile(final File cfile) throws Exception { ClassFile classFile = ClassFile.read(cfile); - boolean methodFound = false; + int methodsFound = 0; for (Method method : classFile.methods) { - if (method.getName(classFile.constant_pool).equals(methodToFind)) { - methodFound = true; + if (method.getName(classFile.constant_pool).startsWith("lambda$")) { + ++methodsFound; Code_attribute code = (Code_attribute) method.attributes.get("Code"); LineNumberTable_attribute lnt = (LineNumberTable_attribute) code.attributes.get("LineNumberTable"); @@ -101,7 +99,7 @@ } } } - Assert.check(methodFound, "The seek method was not found"); + Assert.check(methodsFound == 1, "Expected to find one lambda method, found " + methodsFound); } void error(String msg) { diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/TestSerializedLambdaNameStability.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/TestSerializedLambdaNameStability.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,166 @@ +/* + * 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 8023668 + * @summary Desugar serializable lambda bodies using more robust naming scheme + * @library /tools/javac/lib + * @build ToolBox + * @run main TestSerializedLambdaNameStability + */ + +import java.io.*; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.file.*; + +public class TestSerializedLambdaNameStability { + + final ClassLoader writingClassLoader; + final ClassLoader clonedClassLoader; + final ClassLoader checkingClassLoader; + + TestSerializedLambdaNameStability() { + writingClassLoader = new TestClassLoader("before"); + clonedClassLoader = new TestClassLoader("before"); + checkingClassLoader = new TestClassLoader("after"); + } + + public static void main(String... args) throws Exception { + new TestSerializedLambdaNameStability().doit("NameOfCapturedArgs", true); + new TestSerializedLambdaNameStability().doit("TypesOfCapturedArgs", true); + new TestSerializedLambdaNameStability().doit("OrderOfCapturedArgs", true); + new TestSerializedLambdaNameStability().doit("VariableAssignmentTarget", false); + new TestSerializedLambdaNameStability().doit("TargetName", true); + new TestSerializedLambdaNameStability().doit("TargetType", true); + } + + public void doit(String name, boolean expectFail) throws Exception { + String iName = "I" + name; + String testName = "TEST" + name; + Class kw = writingClassLoader.loadClass(testName); + Object instw = getInstance(kw); + Method mw = getMethod(kw, "write", ObjectOutput.class); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ObjectOutput out = new ObjectOutputStream(baos)) { + mw.invoke(instw, out); + } + byte[] ser = baos.toByteArray(); + + // Read and check clone + readCheck(iName, testName, clonedClassLoader, ser); + System.err.printf("cloned test readCheck %s\n", testName); + + // Read and check other + if (expectFail) { + try { + readCheck(iName, testName, checkingClassLoader, ser); + } catch (InvocationTargetException ite) { + Throwable underlying = ite; + while (underlying != null && !(underlying instanceof IllegalArgumentException)) { + underlying = underlying.getCause(); + } + if (underlying != null) { + if (underlying.getMessage().contains("deserialization")) { + System.err.printf("PASS: other test %s got expected exception %s\n", testName, underlying); + return; + } + } + System.err.printf("FAIL: other test %s got unexpected exception %s\n", testName, ite); + throw new Exception("unexpected exception ", ite); + } + System.err.printf("FAIL: other test %s expected an exception", testName); + throw new Exception("expected an exception" + testName); + } else { + readCheck(iName, testName, checkingClassLoader, ser); + System.err.printf("PASS: other test %s readCheck\n", testName); + } + } + + void readCheck(String iName, String testName, ClassLoader loader, byte[] ser) throws Exception { + Class k = loader.loadClass(testName); + Object inst = getInstance(k); + Method mrc = getMethod(k, "readCheck", ObjectInput.class); + ByteArrayInputStream bais = new ByteArrayInputStream(ser); + try (ObjectInput in = new ObjectInputStream(bais)) { + mrc.invoke(inst, in); + } + } + + Method getMethod(Class k, String name, Class argTypes) throws Exception { + Method meth = k.getDeclaredMethod(name, argTypes); + meth.setAccessible(true); + return meth; + } + + Object getInstance(Class k) throws Exception { + Constructor cons = k.getConstructors()[0]; + cons.setAccessible(true); + return cons.newInstance(); + } + + static class TestClassLoader extends ClassLoader { + static final String compiledDir = System.getProperty("user.dir"); + static final String sourceBaseDir = System.getProperty("test.src"); + + final String context; + + public TestClassLoader(String context) { + super(); + this.context = context; + } + + @Override + public Class findClass(String name) throws ClassNotFoundException { + byte[] b; + + try { + b = loadClassData(name); + } catch (Throwable th) { + // th.printStackTrace(); + throw new ClassNotFoundException("Loading error", th); + } + return defineClass(name, b, 0, b.length); + } + + private byte[] loadClassData(String name) throws Exception { + String srcName; + if (name.startsWith("TEST")) + srcName = name; + else if (name.startsWith("I")) + srcName = "TEST" + name.substring(1); + else + throw new Exception("Did not expect to load " + name); + Path srcFile = Paths.get(sourceBaseDir, context, srcName + ".java"); + String testSource = new String(Files.readAllBytes(srcFile)); + ToolBox.JavaToolArgs javacSuccessArgs = + new ToolBox.JavaToolArgs().setSources(testSource); + ToolBox.javac(javacSuccessArgs); + Path cfFile = Paths.get(compiledDir, name + ".class"); + byte[] bytes = Files.readAllBytes(cfFile); + return bytes; + } + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/after/TESTNameOfCapturedArgs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/after/TESTNameOfCapturedArgs.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,48 @@ +/* + * 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. + */ + +import java.io.*; + +interface INameOfCapturedArgs extends Serializable { + int get(); +} + +class TESTNameOfCapturedArgs { + + public TESTNameOfCapturedArgs() { + } + + public void write(ObjectOutput out) throws IOException { + int y = 44; + INameOfCapturedArgs res = () -> y; + out.writeObject(res); + } + + public void readCheck(ObjectInput in) throws Exception { + INameOfCapturedArgs lam = (INameOfCapturedArgs) in.readObject(); + int val = lam.get(); + if (val != 44) { + throw new IllegalArgumentException("Expected 44"); + } + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/after/TESTOrderOfCapturedArgs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/after/TESTOrderOfCapturedArgs.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,49 @@ +/* + * 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. + */ + +import java.io.*; + +interface IOrderOfCapturedArgs extends Serializable { + String get(); +} + +class TESTOrderOfCapturedArgs { + + public TESTOrderOfCapturedArgs() { + } + + public void write(ObjectOutput out) throws IOException { + String a = "fu"; + String b = "bar"; + IOrderOfCapturedArgs res = () -> b + a; + out.writeObject(res); + } + + public void readCheck(ObjectInput in) throws Exception { + IOrderOfCapturedArgs lam = (IOrderOfCapturedArgs) in.readObject(); + Object val = lam.get(); + if (!val.equals("fubar")) { + throw new IllegalArgumentException("Expected 'fubar'"); + } + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/after/TESTTargetName.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/after/TESTTargetName.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,47 @@ +/* + * 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. + */ + +import java.io.*; + +interface ITargetName extends Serializable { + String get(); +} + +class TESTTargetName { + + public TESTTargetName() { + } + + public void write(ObjectOutput out) throws IOException { + ITargetName resist = () -> "fubar"; + out.writeObject(resist); + } + + public void readCheck(ObjectInput in) throws Exception { + ITargetName lam = (ITargetName) in.readObject(); + Object val = lam.get(); + if (!val.equals("fubar")) { + throw new IllegalArgumentException("Expected 'fubar'"); + } + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/after/TESTTargetType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/after/TESTTargetType.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,40 @@ +/* + * 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. + */ + +import java.io.*; +import java.util.function.*; + +class TESTTargetType { + + public TESTTargetType() { + } + + public void write(ObjectOutput out) throws IOException { + Object res = (Predicate & Serializable) ((str) -> str.length() > 3); + out.writeObject(res); + } + + public void readCheck(ObjectInput in) throws Exception { + in.readObject(); + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/after/TESTTypesOfCapturedArgs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/after/TESTTypesOfCapturedArgs.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,48 @@ +/* + * 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. + */ + +import java.io.*; + +interface ITypesOfCapturedArgs extends Serializable { + Object get(); +} + +class TESTTypesOfCapturedArgs { + + public TESTTypesOfCapturedArgs() { + } + + public void write(ObjectOutput out) throws IOException { + Object x = "hi"; + ITypesOfCapturedArgs res = () -> x; + out.writeObject(res); + } + + public void readCheck(ObjectInput in) throws Exception { + ITypesOfCapturedArgs lam = (ITypesOfCapturedArgs) in.readObject(); + Object val = lam.get(); + if (!val.equals("hi")) { + throw new IllegalArgumentException("Expected 'hi'"); + } + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/after/TESTVariableAssignmentTarget.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/after/TESTVariableAssignmentTarget.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,54 @@ +/* + * 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. + */ + +import java.io.*; + +interface IVariableAssignmentTarget extends Serializable { + String get(); +} + +class TESTVariableAssignmentTarget { + + public TESTVariableAssignmentTarget() { + } + + public void write(ObjectOutput out) throws IOException { + IVariableAssignmentTarget res2 = () -> "bar"; + IVariableAssignmentTarget res1 = () -> "fu"; + out.writeObject(res1); + out.writeObject(res2); + } + + public void readCheck(ObjectInput in) throws Exception { + IVariableAssignmentTarget lam = (IVariableAssignmentTarget) in.readObject(); + Object val = lam.get(); + if (!val.equals("fu")) { + throw new IllegalArgumentException("Expected 'fu'"); + } + lam = (IVariableAssignmentTarget) in.readObject(); + val = lam.get(); + if (!val.equals("bar")) { + throw new IllegalArgumentException("Expected 'bar'"); + } + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/before/TESTNameOfCapturedArgs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/before/TESTNameOfCapturedArgs.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,48 @@ +/* + * 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. + */ + +import java.io.*; + +interface INameOfCapturedArgs extends Serializable { + int get(); +} + +class TESTNameOfCapturedArgs { + + public TESTNameOfCapturedArgs() { + } + + public void write(ObjectOutput out) throws IOException { + int x = 44; + INameOfCapturedArgs res = () -> x; + out.writeObject(res); + } + + public void readCheck(ObjectInput in) throws Exception { + INameOfCapturedArgs lam = (INameOfCapturedArgs) in.readObject(); + int val = lam.get(); + if (val != 44) { + throw new IllegalArgumentException("Expected 44"); + } + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/before/TESTOrderOfCapturedArgs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/before/TESTOrderOfCapturedArgs.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,49 @@ +/* + * 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. + */ + +import java.io.*; + +interface IOrderOfCapturedArgs extends Serializable { + String get(); +} + +class TESTOrderOfCapturedArgs { + + public TESTOrderOfCapturedArgs() { + } + + public void write(ObjectOutput out) throws IOException { + String a = "fu"; + String b = "bar"; + IOrderOfCapturedArgs res = () -> a + b; + out.writeObject(res); + } + + public void readCheck(ObjectInput in) throws Exception { + IOrderOfCapturedArgs lam = (IOrderOfCapturedArgs) in.readObject(); + Object val = lam.get(); + if (!val.equals("fubar")) { + throw new IllegalArgumentException("Expected 'fubar'"); + } + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/before/TESTTargetName.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/before/TESTTargetName.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,47 @@ +/* + * 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. + */ + +import java.io.*; + +interface ITargetName extends Serializable { + String get(); +} + +class TESTTargetName { + + public TESTTargetName() { + } + + public void write(ObjectOutput out) throws IOException { + ITargetName res = () -> "fubar"; + out.writeObject(res); + } + + public void readCheck(ObjectInput in) throws Exception { + ITargetName lam = (ITargetName) in.readObject(); + Object val = lam.get(); + if (!val.equals("fubar")) { + throw new IllegalArgumentException("Expected 'fubar'"); + } + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/before/TESTTargetType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/before/TESTTargetType.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,40 @@ +/* + * 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. + */ + +import java.io.*; +import java.util.function.*; + +class TESTTargetType { + + public TESTTargetType() { + } + + public void write(ObjectOutput out) throws IOException { + Object res = (Function & Serializable) ((str) -> str.length() > 3); + out.writeObject(res); + } + + public void readCheck(ObjectInput in) throws Exception { + in.readObject(); + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/before/TESTTypesOfCapturedArgs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/before/TESTTypesOfCapturedArgs.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,48 @@ +/* + * 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. + */ + +import java.io.*; + +interface ITypesOfCapturedArgs extends Serializable { + Object get(); +} + +class TESTTypesOfCapturedArgs { + + public TESTTypesOfCapturedArgs() { + } + + public void write(ObjectOutput out) throws IOException { + String x = "hi"; + ITypesOfCapturedArgs res = () -> x; + out.writeObject(res); + } + + public void readCheck(ObjectInput in) throws Exception { + ITypesOfCapturedArgs lam = (ITypesOfCapturedArgs) in.readObject(); + Object val = lam.get(); + if (!val.equals("hi")) { + throw new IllegalArgumentException("Expected 'hi'"); + } + } +} diff -r 963c57175e40 -r 6cd16d8ed2b9 test/tools/javac/lambda/lambdaNaming/before/TESTVariableAssignmentTarget.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/lambdaNaming/before/TESTVariableAssignmentTarget.java Tue Oct 22 16:53:21 2013 -0700 @@ -0,0 +1,54 @@ +/* + * 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. + */ + +import java.io.*; + +interface IVariableAssignmentTarget extends Serializable { + String get(); +} + +class TESTVariableAssignmentTarget { + + public TESTVariableAssignmentTarget() { + } + + public void write(ObjectOutput out) throws IOException { + IVariableAssignmentTarget res1 = () -> "fu"; + IVariableAssignmentTarget res2 = () -> "bar"; + out.writeObject(res1); + out.writeObject(res2); + } + + public void readCheck(ObjectInput in) throws Exception { + IVariableAssignmentTarget lam = (IVariableAssignmentTarget) in.readObject(); + Object val = lam.get(); + if (!val.equals("fu")) { + throw new IllegalArgumentException("Expected 'fu'"); + } + lam = (IVariableAssignmentTarget) in.readObject(); + val = lam.get(); + if (!val.equals("bar")) { + throw new IllegalArgumentException("Expected 'bar'"); + } + } +}