8023668: Desugar serializable lambda bodies using more robust naming scheme

Lambda / bridged method-reference naming overhaul

Reviewed-by: ksrini, briangoetz
This commit is contained in:
Robert Field 2013-10-22 16:53:21 -07:00
parent 48b6b38e52
commit 69709943c3
16 changed files with 962 additions and 78 deletions

View File

@ -30,7 +30,6 @@ import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
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 @@ public class LambdaToMethod extends TreeTranslator {
DiagnosticPosition pos, List<Object> 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<JCExpression> serArgs = new ListBuffer<>();
@ -1087,8 +1086,21 @@ public class LambdaToMethod extends TreeTranslator {
* keep the count of lambda expression defined in given context (used to
* generate unambiguous names for serializable lambdas)
*/
private Map<String, Integer> serializableLambdaCounts =
new HashMap<String, Integer>();
private class SyntheticMethodNameCounter {
private Map<String, Integer> 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<Symbol, JCClassDecl> localClassDefs;
@ -1122,13 +1134,13 @@ public class LambdaToMethod extends TreeTranslator {
@Override
public void visitClassDef(JCClassDecl tree) {
List<Frame> prevStack = frameStack;
Map<String, Integer> prevSerializableLambdaCount =
serializableLambdaCounts;
SyntheticMethodNameCounter prevSyntheticMethodNameCounts =
syntheticMethodNameCounts;
Map<ClassSymbol, Symbol> prevClinits = clinits;
DiagnosticSource prevSource = log.currentSource();
try {
log.useSource(tree.sym.sourcefile);
serializableLambdaCounts = new HashMap<String, Integer>();
syntheticMethodNameCounts = new SyntheticMethodNameCounter();
prevClinits = new HashMap<ClassSymbol, Symbol>();
if (tree.sym.owner.kind == MTH) {
localClassDefs.put(tree.sym, tree);
@ -1154,7 +1166,7 @@ public class LambdaToMethod extends TreeTranslator {
finally {
log.useSource(prevSource.getFile());
frameStack = prevStack;
serializableLambdaCounts = prevSerializableLambdaCount;
syntheticMethodNameCounts = prevSyntheticMethodNameCounts;
clinits = prevClinits;
}
}
@ -1379,50 +1391,6 @@ public class LambdaToMethod extends TreeTranslator {
}
}
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("<clinit>"))
methodName = "static";
else if (methodName.equals("<init>"))
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 @@ public class LambdaToMethod extends TreeTranslator {
private abstract class TranslationContext<T extends JCFunctionalExpression> {
/** 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<Symbol> bridges;
final List<Symbol> bridges;
TranslationContext(T tree) {
this.tree = tree;
@ -1679,6 +1647,31 @@ public class LambdaToMethod extends TreeTranslator {
}
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("<clinit>")) {
methodName = "static";
} else if (methodName.equals("<init>")) {
methodName = "new";
}
return methodName;
}
}
/**
@ -1690,7 +1683,10 @@ public class LambdaToMethod extends TreeTranslator {
private class LambdaTranslationContext extends TranslationContext<JCLambda> {
/** 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<LambdaSymbolKind, Map<Symbol, Symbol>> translatedSymbols;
@ -1702,11 +1698,22 @@ public class LambdaToMethod extends TreeTranslator {
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 @@ public class LambdaToMethod extends TreeTranslator {
translatedSymbols.put(TYPE_VAR, new LinkedHashMap<Symbol, Symbol>());
}
/**
* 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 @@ public class LambdaToMethod extends TreeTranslator {
}
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 @@ public class LambdaToMethod extends TreeTranslator {
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,13 +1978,71 @@ public class LambdaToMethod extends TreeTranslator {
* 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() {
return tree.varargsElement != null;
}
/**
* 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()
*/
@ -1954,7 +2102,7 @@ public class LambdaToMethod extends TreeTranslator {
* ****************************************************************
*/
private String methodSig(Type type) {
private String typeSig(Type type) {
L2MSignatureGenerator sg = new L2MSignatureGenerator();
sg.assembleSig(type);
return sg.toString();

View File

@ -1,7 +1,7 @@
class LambdaTest --
LambdaTest.<init>()
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)
LambdaTest$I.m(x)

View File

@ -61,8 +61,6 @@ public class WrongLVTForLambdaTest {
{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 @@ public class WrongLVTForLambdaTest {
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 @@ public class WrongLVTForLambdaTest {
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 @@ public class WrongLVTForLambdaTest {
}
}
}
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) {

View File

@ -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;
}
}
}

View File

@ -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");
}
}
}

View File

@ -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'");
}
}
}

View File

@ -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'");
}
}
}

View File

@ -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<String> & Serializable) ((str) -> str.length() > 3);
out.writeObject(res);
}
public void readCheck(ObjectInput in) throws Exception {
in.readObject();
}
}

View File

@ -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'");
}
}
}

View File

@ -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'");
}
}
}

View File

@ -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");
}
}
}

View File

@ -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'");
}
}
}

View File

@ -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'");
}
}
}

View File

@ -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<String, Boolean> & Serializable) ((str) -> str.length() > 3);
out.writeObject(res);
}
public void readCheck(ObjectInput in) throws Exception {
in.readObject();
}
}

View File

@ -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'");
}
}
}

View File

@ -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'");
}
}
}