8003639: convert lambda testng tests to jtreg and add them

Reviewed-by: mcimadamore
This commit is contained in:
Robert Field 2012-11-20 09:58:55 -08:00
parent d1eede168b
commit d1a78e2021
48 changed files with 6900 additions and 252 deletions

View file

@ -0,0 +1,137 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng DefaultMethodRegressionTests
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
/**
* This set of classes/interfaces (K/I/C) is specially designed to expose a
* bug in the JVM where it did not find some overloaded methods in some
* specific situations. (fixed by hotspot changeset ffb9316fd9ed)
*/
interface K {
int bbb(Long l);
}
interface I extends K {
default void aaa() {}
default void aab() {}
default void aac() {}
default int bbb(Integer i) { return 22; }
default int bbb(Float f) { return 33; }
default int bbb(Long l) { return 44; }
default int bbb(Double d) { return 55; }
default int bbb(String s) { return 66; }
default void caa() {}
default void cab() {}
default void cac() {}
}
class C implements I {}
public class DefaultMethodRegressionTests {
@Test(groups = "vm")
public void testLostOverloadedMethod() {
C c = new C();
assertEquals(c.bbb(new Integer(1)), 22);
assertEquals(c.bbb(new Float(1.1)), 33);
assertEquals(c.bbb(new Long(1L)), 44);
assertEquals(c.bbb(new Double(0.01)), 55);
assertEquals(c.bbb(new String("")), 66);
}
// Test to ensure that the inference verifier accepts older classfiles
// with classes that implement interfaces with defaults.
@Test(groups = "vm")
public void testInferenceVerifier() {
// interface I { int m() default { return 99; } }
byte I_bytes[] = {
(byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x33,
0x00, 0x08, 0x07, 0x00, 0x06, 0x07, 0x00, 0x07,
0x01, 0x00, 0x03, 0x66, 0x6f, 0x6f, 0x01, 0x00,
0x03, 0x28, 0x29, 0x49, 0x01, 0x00, 0x04, 0x43,
0x6f, 0x64, 0x65, 0x01, 0x00, 0x01, 0x49, 0x01,
0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x06, 0x00, 0x00, 0x01, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01,
0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05,
0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x01,
0x00, 0x00, 0x00, 0x03, 0x10, 0x63, (byte)0xac, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00
};
// public class C implements I {} /* -target 1.5 */
byte C_bytes[] = {
(byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x31,
0x00, 0x0c, 0x0a, 0x00, 0x03, 0x00, 0x08, 0x07,
0x00, 0x09, 0x07, 0x00, 0x0a, 0x07, 0x00, 0x0b,
0x01, 0x00, 0x06, 0x3c, 0x69, 0x6e, 0x69, 0x74,
0x3e, 0x01, 0x00, 0x03, 0x28, 0x29, 0x56, 0x01,
0x00, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x0c, 0x00,
0x05, 0x00, 0x06, 0x01, 0x00, 0x01, 0x43, 0x01,
0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x01, 0x00, 0x01, 0x49, 0x00, 0x21,
0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04,
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05,
0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00,
0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
0x00, 0x05, 0x2a, (byte)0xb7, 0x00, 0x01, (byte)0xb1, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00
};
ClassLoader cl = new ClassLoader() {
protected Class<?> findClass(String name) {
if (name.equals("I")) {
return defineClass("I", I_bytes, 0, I_bytes.length);
} else if (name.equals("C")) {
return defineClass("C", C_bytes, 0, C_bytes.length);
} else {
return null;
}
}
};
try {
Class.forName("C", true, cl);
} catch (Exception e) {
// unmodified verifier will throw VerifyError
fail("No exception should be thrown");
}
}
}

View file

@ -1,206 +0,0 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package shapegen;
import java.util.HashSet;
import java.util.Set;
import static shapegen.ClassCase.Kind.*;
/**
*
* @author Robert Field
*/
public class RuleGroup {
final String name;
private final Rule[] rules;
public RuleGroup(String name, Rule[] rules) {
this.name = name;
this.rules = rules;
}
public boolean exec(ClassCase cc) {
boolean found = false;
for (Rule rule : rules) {
if (rule.guard(cc)) {
if (found) {
throw new RuntimeException("Bad rules -- multiple matches " + toString() + " for " + cc);
} else {
rule.eval(cc);
found = true;
}
}
}
return found;
}
@Override
public String toString() {
return name;
}
public static RuleGroup PROVENENCE = new RuleGroup("Provenence", new Rule[] {
new Rule("P-CDeclare") {
boolean guard(ClassCase cc) {
return cc.isa(CCONCRETE, CABSTRACT);
}
void eval(ClassCase cc) {
cc.set_mprov(cc);
cc.set_HasClassMethod(true);
}
},
new Rule("P-IDeclare") {
boolean guard(ClassCase cc) {
return cc.isa(IDEFAULT, IPRESENT);
}
void eval(ClassCase cc) {
cc.set_mprov(cc);
}
},
new Rule("P-IntfInh") {
boolean guard(ClassCase cc) {
return cc.isa(IVAC, CNONE) && !(cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
}
void eval(ClassCase cc) {
Set<ClassCase> _S = new HashSet<>();
for (ClassCase t : cc.getSupertypes()) {
_S.addAll(t.get_mprov());
}
Set<ClassCase> tops = new HashSet<>();
for (ClassCase _W : _S) {
for (ClassCase _V : _S) {
if (_V.equals(_W) || !(_V.isSubtypeOf(_W))) {
tops.add(_W);
}
}
}
cc.set_mprov(tops);
}
},
new Rule("P-ClassInh") {
boolean guard(ClassCase cc) {
return cc.isa(CNONE) && (cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
}
void eval(ClassCase cc) {
cc.set_mprov(cc.getSuperclass());
cc.set_HasClassMethod(true);
}
},
});
public static RuleGroup MARKER = new RuleGroup("Marker", new Rule[] {
new Rule("M-Default") {
boolean guard(ClassCase cc) {
return cc.isa(IDEFAULT);
}
void eval(ClassCase cc) {
cc.set_HasDefault(true);
}
},
new Rule("M-Conc") {
boolean guard(ClassCase cc) {
return cc.isa(CCONCRETE);
}
void eval(ClassCase cc) {
cc.set_IsConcrete(true);
}
},
});
public static RuleGroup RESOLUTION = new RuleGroup("Resolution", new Rule[] {
new Rule("R-Resolve") {
boolean guard(ClassCase cc) {
if (!(cc.isClass() && cc.get_mprov().size() == 1)) {
return false;
}
ClassCase _V = cc.get_mprov().iterator().next();
return _V.get_IsConcrete() || _V.get_HasDefault();
}
void eval(ClassCase cc) {
ClassCase _V = cc.get_mprov().iterator().next();
cc.set_mres(_V);
}
},
});
public static RuleGroup DEFENDER = new RuleGroup("Defender", new Rule[] {
new Rule("D-Defend") {
boolean guard(ClassCase cc) {
ClassCase mresSuper = cc.hasSuperclass() ? cc.getSuperclass().get_mres() : null;
boolean eq = cc.get_mres() == null ? mresSuper == null : cc.get_mres().equals(mresSuper);
return cc.isa(CNONE) && !eq;
}
void eval(ClassCase cc) {
cc.set_mdefend(cc.get_mres());
}
},
});
public static RuleGroup CHECKING = new RuleGroup("Checking", new Rule[] {
new Rule("C-Check") {
boolean guard(ClassCase cc) {
for (ClassCase t : cc.getSupertypes()) {
if (! t.get_OK()) {
return false;
}
}
int defenderCount = 0;
int provCount = 0;
for (ClassCase prov : cc.get_mprov()) {
if (prov.get_HasDefault()) {
defenderCount++;
}
provCount++;
}
return provCount <= 1 || defenderCount == 0;
}
void eval(ClassCase cc) {
cc.set_OK(true);
}
},
});
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng InInterface
*/
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
interface LTII {
interface ILsp1 {
String m();
}
interface ILsp2 {
String m(String x);
}
default ILsp1 t1() {
return () -> { return "yo"; };
}
default ILsp2 t2() {
return (x) -> { return "snur" + x; };
}
}
@Test
public class InInterface implements LTII {
public void testLambdaInDefaultMethod() {
assertEquals(t1().m(), "yo");
assertEquals(t2().m("p"), "snurp");
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng InnerConstructor
*/
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
@Test
public class InnerConstructor {
public void testLambdaWithInnerConstructor() {
assertEquals(seq1().m().toString(), "Cbl:nada");
assertEquals(seq2().m("rats").toString(), "Cbl:rats");
}
Ib1 seq1() {
return () -> { return new Cbl(); };
}
Ib2 seq2() {
return (x) -> { return new Cbl(x); };
}
class Cbl {
String val;
Cbl() {
this.val = "nada";
}
Cbl(String z) {
this.val = z;
}
public String toString() {
return "Cbl:" + val;
}
}
interface Ib1 {
Object m();
}
interface Ib2 {
Object m(String x);
}
}

View file

@ -0,0 +1,234 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng LambdaTranslationTest1
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
@Test
public class LambdaTranslationTest1 extends LT1Sub {
String cntxt = "blah";
private static final ThreadLocal<Object> result = new ThreadLocal<>();
private static void setResult(Object s) { result.set(s); }
private static void appendResult(Object s) { result.set(result.get().toString() + s); }
private static void assertResult(String expected) {
assertEquals(result.get().toString(), expected);
}
static Integer count(String s) {
return s.length();
}
static int icount(String s) {
return s.length();
}
static void eye(Integer i) {
setResult(String.format("I:%d", i));
}
static void ieye(int i) {
setResult(String.format("i:%d", i));
}
static void deye(double d) {
setResult(String.format("d:%f", d));
}
public void testLambdas() {
TBlock<Object> b = t -> {setResult("Sink0::" + t);};
b.apply("Howdy");
assertResult("Sink0::Howdy");
TBlock<String> b1 = t -> {setResult("Sink1::" + t);};
b1.apply("Rowdy");
assertResult("Sink1::Rowdy");
for (int i = 5; i < 10; ++i) {
TBlock<Integer> b2 = t -> {setResult("Sink2::" + t);};
b2.apply(i);
assertResult("Sink2::" + i);
}
TBlock<Integer> b3 = t -> {setResult("Sink3::" + t);};
for (int i = 900; i > 0; i -= 100) {
b3.apply(i);
assertResult("Sink3::" + i);
}
cntxt = "blah";
TBlock<String> b4 = t -> {setResult(String.format("b4: %s .. %s", cntxt, t));};
b4.apply("Yor");
assertResult("b4: blah .. Yor");
String flaw = "flaw";
TBlock<String> b5 = t -> {setResult(String.format("b5: %s .. %s", flaw, t));};
b5.apply("BB");
assertResult("b5: flaw .. BB");
cntxt = "flew";
TBlock<String> b6 = t -> {setResult(String.format("b6: %s .. %s .. %s", t, cntxt, flaw));};
b6.apply("flee");
assertResult("b6: flee .. flew .. flaw");
TBlock<String> b7 = t -> {setResult(String.format("b7: %s %s", t, this.protectedSuperclassMethod()));};
b7.apply("this:");
assertResult("b7: this: instance:flew");
TBlock<String> b8 = t -> {setResult(String.format("b8: %s %s", t, super.protectedSuperclassMethod()));};
b8.apply("super:");
assertResult("b8: super: I'm the sub");
TBlock<String> b7b = t -> {setResult(String.format("b9: %s %s", t, protectedSuperclassMethod()));};
b7b.apply("implicit this:");
assertResult("b9: implicit this: instance:flew");
TBlock<Object> b10 = t -> {setResult(String.format("b10: new LT1Thing: %s", (new LT1Thing(t)).str));};
b10.apply("thing");
assertResult("b10: new LT1Thing: thing");
TBlock<Object> b11 = t -> {setResult(String.format("b11: %s", (new LT1Thing(t) {
String get() {
return "*" + str.toString() + "*";
}
}).get()));};
b11.apply(999);
assertResult("b11: *999*");
}
public void testMethodRefs() {
LT1IA ia = LambdaTranslationTest1::eye;
ia.doit(1234);
assertResult("I:1234");
LT1IIA iia = LambdaTranslationTest1::ieye;
iia.doit(1234);
assertResult("i:1234");
LT1IA da = LambdaTranslationTest1::deye;
da.doit(1234);
assertResult("d:1234.000000");
LT1SA a = LambdaTranslationTest1::count;
assertEquals((Integer) 5, a.doit("howdy"));
a = LambdaTranslationTest1::icount;
assertEquals((Integer) 6, a.doit("shower"));
}
public void testInner() throws Exception {
(new In()).doInner();
}
protected String protectedSuperclassMethod() {
return "instance:" + cntxt;
}
private class In {
private int that = 1234;
void doInner() {
TBlock<String> i4 = t -> {setResult(String.format("i4: %d .. %s", that, t));};
i4.apply("=1234");
assertResult("i4: 1234 .. =1234");
TBlock<String> i5 = t -> {setResult(""); appendResult(t); appendResult(t);};
i5.apply("fruit");
assertResult("fruitfruit");
cntxt = "human";
TBlock<String> b4 = t -> {setResult(String.format("b4: %s .. %s", cntxt, t));};
b4.apply("bin");
assertResult("b4: human .. bin");
final String flaw = "flaw";
/**
Callable<String> c5 = () -> "["+flaw+"]" ;
System.out.printf("c5: %s\n", c5.call() );
**/
TBlock<String> b5 = t -> {setResult(String.format("b5: %s .. %s", flaw, t));};
b5.apply("BB");
assertResult("b5: flaw .. BB");
cntxt = "borg";
TBlock<String> b6 = t -> {setResult(String.format("b6: %s .. %s .. %s", t, cntxt, flaw));};
b6.apply("flee");
assertResult("b6: flee .. borg .. flaw");
TBlock<String> b7b = t -> {setResult(String.format("b7b: %s %s", t, protectedSuperclassMethod()));};
b7b.apply("implicit outer this");
assertResult("b7b: implicit outer this instance:borg");
/**
TBlock<Object> b9 = t -> { System.out.printf("New: %s\n", (new LT1Thing(t)).str); };
b9.apply("thing");
TBlock<Object> ba = t -> { System.out.printf("Def: %s\n", (new LT1Thing(t) { String get() { return "*" + str.toString() +"*";}}).get() ); };
ba.apply(999);
*/
}
}
}
class LT1Sub {
protected String protectedSuperclassMethod() {
return "I'm the sub";
}
}
class LT1Thing {
final Object str;
LT1Thing(Object s) {
str = s;
}
}
interface LT1SA {
Integer doit(String s);
}
interface LT1IA {
void doit(int i);
}
interface LT1IIA {
void doit(Integer i);
}

View file

@ -0,0 +1,355 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng LambdaTranslationTest2
*/
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.List;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
/**
* LambdaTranslationTest2 -- end-to-end smoke tests for lambda evaluation
*/
@Test
public class LambdaTranslationTest2 {
final String dummy = "dummy";
public void testLambdas() {
TPredicate<String> isEmpty = s -> s.isEmpty();
assertTrue(isEmpty.test(""));
assertTrue(!isEmpty.test("foo"));
TPredicate<Object> oIsEmpty = s -> ((String) s).isEmpty();
assertTrue(oIsEmpty.test(""));
assertTrue(!oIsEmpty.test("foo"));
TPredicate<Object> alwaysTrue = o -> true;
assertTrue(alwaysTrue.test(""));
assertTrue(alwaysTrue.test(null));
TPredicate<Object> alwaysFalse = o -> false;
assertTrue(!alwaysFalse.test(""));
assertTrue(!alwaysFalse.test(null));
// tests local capture
String foo = "foo";
TPredicate<String> equalsFoo = s -> s.equals(foo);
assertTrue(!equalsFoo.test(""));
assertTrue(equalsFoo.test("foo"));
// tests instance capture
TPredicate<String> equalsDummy = s -> s.equals(dummy);
assertTrue(!equalsDummy.test(""));
assertTrue(equalsDummy.test("dummy"));
TMapper<Object, Object> ident = s -> s;
assertEquals("blarf", ident.map("blarf"));
assertEquals("wooga", ident.map("wooga"));
assertTrue("wooga" == ident.map("wooga"));
// constant capture
TMapper<Object, Object> prefixer = s -> "p" + s;
assertEquals("pblarf", prefixer.map("blarf"));
assertEquals("pwooga", prefixer.map("wooga"));
// instance capture
TMapper<Object, Object> prefixer2 = s -> dummy + s;
assertEquals("dummyblarf", prefixer2.map("blarf"));
assertEquals("dummywooga", prefixer2.map("wooga"));
}
interface Factory<T> {
T make();
}
interface StringFactory extends Factory<String> { }
interface StringFactory2 extends Factory<String> {
String make();
}
public void testBridges() {
Factory<String> of = () -> "y";
Factory<?> ef = () -> "z";
assertEquals("y", of.make());
assertEquals("y", ((Factory<?>) of).make());
assertEquals("y", ((Factory) of).make());
assertEquals("z", ef.make());
assertEquals("z", ((Factory) ef).make());
}
public void testBridgesImplicitSpecialization() {
StringFactory sf = () -> "x";
assertEquals("x", sf.make());
assertEquals("x", ((Factory<String>) sf).make());
assertEquals("x", ((Factory<?>) sf).make());
assertEquals("x", ((Factory) sf).make());
}
public void testBridgesExplicitSpecialization() {
StringFactory2 sf = () -> "x";
assertEquals("x", sf.make());
assertEquals("x", ((Factory<String>) sf).make());
assertEquals("x", ((Factory<?>) sf).make());
assertEquals("x", ((Factory) sf).make());
}
public void testSuperCapture() {
class A {
String make() { return "x"; }
}
class B extends A {
void testSuperCapture() {
StringFactory sf = () -> super.make();
assertEquals("x", sf.make());
}
}
new B().testSuperCapture();
}
interface WidenD {
public String m(float a0, double a1);
}
interface WidenS {
public String m(byte a0, short a1);
}
interface WidenI {
public String m(byte a0, short a1, char a2, int a3);
}
interface WidenL {
public String m(byte a0, short a1, char a2, int a3, long a4);
}
interface Box {
public String m(byte a0, short a1, char a2, int a3, long a4, boolean a5, float a6, double a7);
}
static String pb(Byte a0, Short a1, Character a2, Integer a3, Long a4, Boolean a5, Float a6, Double a7) {
return String.format("b%d s%d c%c i%d j%d z%b f%f d%f", a0, a1, a2, a3, a4, a5, a6, a7);
}
static String pwI1(int a0, int a1, int a2, int a3) {
return String.format("b%d s%d c%d i%d", a0, a1, a2, a3);
}
static String pwI2(Integer a0, Integer a1, Integer a2, Integer a3) {
return String.format("b%d s%d c%d i%d", a0, a1, a2, a3);
}
static String pwL1(long a0, long a1, long a2, long a3, long a4) {
return String.format("b%d s%d c%d i%d j%d", a0, a1, a2, a3, a4);
}
static String pwL2(Long a0, Long a1, Long a2, Long a3, Long a4) {
return String.format("b%d s%d c%d i%d j%d", a0, a1, a2, a3, a4);
}
static String pwS1(short a0, short a1) {
return String.format("b%d s%d", a0, a1);
}
static String pwS2(Short a0, Short a1) {
return String.format("b%d s%d", a0, a1);
}
static String pwD1(double a0, double a1) {
return String.format("f%f d%f", a0, a1);
}
static String pwD2(Double a0, Double a1) {
return String.format("f%f d%f", a0, a1);
}
public void testPrimitiveWidening() {
WidenS ws1 = LambdaTranslationTest2::pwS1;
assertEquals("b1 s2", ws1.m((byte) 1, (short) 2));
WidenD wd1 = LambdaTranslationTest2::pwD1;
assertEquals("f1.000000 d2.000000", wd1.m(1.0f, 2.0));
WidenI wi1 = LambdaTranslationTest2::pwI1;
assertEquals("b1 s2 c3 i4", wi1.m((byte) 1, (short) 2, (char) 3, 4));
WidenL wl1 = LambdaTranslationTest2::pwL1;
assertEquals("b1 s2 c3 i4 j5", wl1.m((byte) 1, (short) 2, (char) 3, 4, 5L));
// @@@ TODO: clarify spec on widen+box conversion
}
interface Unbox {
public String m(Byte a0, Short a1, Character a2, Integer a3, Long a4, Boolean a5, Float a6, Double a7);
}
static String pu(byte a0, short a1, char a2, int a3, long a4, boolean a5, float a6, double a7) {
return String.format("b%d s%d c%c i%d j%d z%b f%f d%f", a0, a1, a2, a3, a4, a5, a6, a7);
}
public void testUnboxing() {
Unbox u = LambdaTranslationTest2::pu;
assertEquals("b1 s2 cA i4 j5 ztrue f6.000000 d7.000000", u.m((byte)1, (short) 2, 'A', 4, 5L, true, 6.0f, 7.0));
}
public void testBoxing() {
Box b = LambdaTranslationTest2::pb;
assertEquals("b1 s2 cA i4 j5 ztrue f6.000000 d7.000000", b.m((byte) 1, (short) 2, 'A', 4, 5L, true, 6.0f, 7.0));
}
static boolean cc(Object o) {
return ((String) o).equals("foo");
}
public void testArgCastingAdaptation() {
TPredicate<String> p = LambdaTranslationTest2::cc;
assertTrue(p.test("foo"));
assertTrue(!p.test("bar"));
}
interface SonOfPredicate<T> extends TPredicate<T> { }
public void testExtendsSAM() {
SonOfPredicate<String> p = s -> s.isEmpty();
assertTrue(p.test(""));
assertTrue(!p.test("foo"));
}
public void testConstructorRef() {
Factory<List<String>> lf = ArrayList<String>::new;
List<String> list = lf.make();
assertTrue(list instanceof ArrayList);
assertTrue(list != lf.make());
list.add("a");
assertEquals("[a]", list.toString());
}
private static String privateMethod() {
return "private";
}
public void testPrivateMethodRef() {
Factory<String> sf = LambdaTranslationTest2::privateMethod;
assertEquals("private", sf.make());
}
private interface PrivateIntf {
String make();
}
public void testPrivateIntf() {
PrivateIntf p = () -> "foo";
assertEquals("foo", p.make());
}
interface Op<T> {
public T op(T a, T b);
}
public void testBoxToObject() {
Op<Integer> maxer = Math::max;
for (int i=-100000; i < 100000; i += 100)
for (int j=-100000; j < 100000; j += 99) {
assertEquals((int) maxer.op(i,j), Math.max(i,j));
}
}
protected static String protectedMethod() {
return "protected";
}
public void testProtectedMethodRef() {
Factory<String> sf = LambdaTranslationTest2::protectedMethod;
assertEquals("protected", sf.make());
}
class Inner1 {
String m1() {
return "Inner1.m1()";
}
class Inner2 {
public String m1() {
return "Inner1.Inner2.m1()";
}
protected String m2() {
return "Inner1.Inner2.m2()";
}
String m3() {
return "Inner1.Inner2.m3()";
}
class Inner3<T> {
T t = null;
Inner3(T t) {
this.t = t;
}
T m1() {
return t;
}
}
}
}
public void testInnerClassMethodRef() {
Factory<String> fs = new Inner1()::m1;
assertEquals("Inner1.m1()", fs.make());
fs = new Inner1().new Inner2()::m1;
assertEquals("Inner1.Inner2.m1()", fs.make());
fs = new Inner1().new Inner2()::m2;
assertEquals("Inner1.Inner2.m2()", fs.make());
fs = new Inner1().new Inner2()::m3;
assertEquals("Inner1.Inner2.m3()", fs.make());
fs = new Inner1().new Inner2().new Inner3<String>("Inner1.Inner2.Inner3")::m1;
assertEquals("Inner1.Inner2.Inner3", fs.make());
Factory<Integer> fsi = new Inner1().new Inner2().new Inner3<Integer>(100)::m1;
assertEquals(100, (int)fsi.make());
}
}

View file

@ -0,0 +1,36 @@
/**
* Performs operations upon an input object which may modify that object and/or
* external state (other objects).
*
* <p>All block implementations are expected to:
* <ul>
* <li>When used for aggregate operations upon many elements blocks
* should not assume that the {@code apply} operation will be called upon
* elements in any specific order.</li>
* </ul>
*
* @param <T> The type of input objects to {@code apply}.
*/
public interface TBlock<T> {
/**
* Performs operations upon the provided object which may modify that object
* and/or external state.
*
* @param t an input object
*/
void apply(T t);
/**
* Returns a Block which performs in sequence the {@code apply} methods of
* multiple Blocks. This Block's {@code apply} method is performed followed
* by the {@code apply} method of the specified Block operation.
*
* @param other an additional Block which will be chained after this Block
* @return a Block which performs in sequence the {@code apply} method of
* this Block and the {@code apply} method of the specified Block operation
*/
public default TBlock<T> chain(TBlock<? super T> other) {
return (T t) -> { apply(t); other.apply(t); };
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2010, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
/**
* Given an input object maps to an appropriate output object. A mapper may
* variously provide a mapping between types, object instances or keys and
* values or any other form of transformation upon the input.
*
* <p/>All mapper implementations are expected to:
* <ul>
* <li>Provide stable results such that for any {@code t} the result of two
* {@code map} operations are always equivalent. ie.<pre>
* Foo one = mapper.map(a);
* Foo two = mapper.map(a);
*
* assert one.equals(two) && two.equals(one);
* </pre></li>
* <li>Equivalent input objects should map to equivalent output objects. ie.<pre>
* assert a.equals(b); // a and b are equivalent
*
* Foo x = mapper.map(a);
* Foo y = mapper.map(b);
*
* assert x.equals(y); // their mapped results should be as equivalent.
* </pre></li>
* <li>The mapper should not modify the input object in any way that would
* change the mapping.</li>
* <li>When used for aggregate operations upon many elements mappers
* should not assume that the {@code map} operation will be called upon elements
* in any specific order.</li>
* </ul>
*
* @param <R> the type of output objects from {@code map} operation. May be the
* @param <T> the type of input objects provided to the {@code map} operation.
* same type as {@code <T>}.
*/
public interface TMapper<R, T> {
/**
* Map the provided input object to an appropriate output object.
*
* @param t the input object to be mapped.
* @return the mapped output object.
*/
R map(T t);
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2010, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
/**
* Determines if the input object matches some criteria.
*
* <p>All predicate implementations are expected to:
* <ul>
* <li>Provide stable results such that for any {@code t} the result of two
* {@code eval} operations are always equivalent. ie.<pre>
* boolean one = predicate.test(a);
* boolean two = predicate.test(a);
*
* assert one == two;
* </pre></li>
* <li>Equivalent input objects should map to equivalent output objects. ie.<pre>
* assert a.equals(b); // a and b are equivalent
*
* boolean x = predicate.test(a);
* boolean y = predicate.test(ab;
*
* assert x == y; // their test results should be the same.
* </pre></li>
* <li>The predicate should not modify the input object in any way that would
* change the evaluation.</li>
* <li>When used for aggregate operations upon many elements predicates
* should not assume that the {@code test} operation will be called upon
* elements in any specific order.</li>
* </ul>
*
* @param <T> the type of input objects provided to {@code test}.
*/
public interface TPredicate<T> {
/**
* Return {@code true} if the input object matches some criteria.
*
* @param t the input object.
* @return {@code true} if the input object matched some criteria.
*/
boolean test(T t);
}

View file

@ -0,0 +1,154 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestFDCCE
*/
import org.testng.annotations.Test;
import java.lang.reflect.Array;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
/**
* Method references and raw types.
* @author Robert Field
*/
@Test
@SuppressWarnings({"rawtypes", "unchecked"})
public class MethodReferenceTestFDCCE {
static void assertCCE(Throwable t) {
assertEquals(t.getClass().getName(), "java.lang.ClassCastException");
}
interface Pred<T> { boolean accept(T x); }
interface Ps { boolean accept(short x); }
interface Oo { Object too(int x); }
interface Reto<T> { T m(); }
class A {}
class B extends A {}
static boolean isMinor(int x) {
return x < 18;
}
static boolean tst(A x) {
return true;
}
static Object otst(Object x) {
return x;
}
static boolean stst(Short x) {
return x < 18;
}
static short ritst() {
return 123;
}
public void testMethodReferenceFDPrim1() {
Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
Pred p2 = p;
assertTrue(p2.accept((Byte)(byte)15));
}
public void testMethodReferenceFDPrim2() {
Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
Pred p2 = p;
assertTrue(p2.accept((byte)15));
}
public void testMethodReferenceFDPrimICCE() {
Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
Pred p2 = p;
try {
p2.accept(15); // should throw CCE
fail("Exception should have been thrown");
} catch (Throwable t) {
assertCCE(t);
}
}
public void testMethodReferenceFDPrimOCCE() {
Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
Pred p2 = p;
try {
p2.accept(new Object()); // should throw CCE
fail("Exception should have been thrown");
} catch (Throwable t) {
assertCCE(t);
}
}
public void testMethodReferenceFDRef() {
Pred<B> p = MethodReferenceTestFDCCE::tst;
Pred p2 = p;
assertTrue(p2.accept(new B()));
}
public void testMethodReferenceFDRefCCE() {
Pred<B> p = MethodReferenceTestFDCCE::tst;
Pred p2 = p;
try {
p2.accept(new A()); // should throw CCE
fail("Exception should have been thrown");
} catch (Throwable t) {
assertCCE(t);
}
}
public void testMethodReferenceFDPrimPrim() {
Ps p = MethodReferenceTestFDCCE::isMinor;
assertTrue(p.accept((byte)15));
}
public void testMethodReferenceFDPrimBoxed() {
Ps p = MethodReferenceTestFDCCE::stst;
assertTrue(p.accept((byte)15));
}
public void testMethodReferenceFDPrimRef() {
Oo p = MethodReferenceTestFDCCE::otst;
assertEquals(p.too(15).getClass().getName(), "java.lang.Integer");
}
public void testMethodReferenceFDRet1() {
Reto<Short> p = MethodReferenceTestFDCCE::ritst;
assertEquals(p.m(), (Short)(short)123);
}
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestInnerDefault
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
interface IDSs { String m(String a); }
interface InDefA {
default String xsA__(String s) {
return "A__xsA:" + s;
}
default String xsAB_(String s) {
return "AB_xsA:" + s;
}
}
interface InDefB extends InDefA {
default String xsAB_(String s) {
return "AB_xsB:" + s;
}
default String xs_B_(String s) {
return "_B_xsB:" + s;
}
}
@Test
public class MethodReferenceTestInnerDefault implements InDefB {
public void testMethodReferenceInnerDefault() {
(new In()).testMethodReferenceInnerDefault();
}
class In {
public void testMethodReferenceInnerDefault() {
IDSs q;
q = MethodReferenceTestInnerDefault.this::xsA__;
assertEquals(q.m("*"), "A__xsA:*");
q = MethodReferenceTestInnerDefault.this::xsAB_;
assertEquals(q.m("*"), "AB_xsB:*");
q = MethodReferenceTestInnerDefault.this::xs_B_;
assertEquals(q.m("*"), "_B_xsB:*");
}
}
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestInnerInstance
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
@Test
public class MethodReferenceTestInnerInstance {
public void testMethodReferenceInnerInstance() {
cia().cib().testMethodReferenceInstance();
}
public void testMethodReferenceInnerExternal() {
cia().cib().testMethodReferenceExternal();
}
interface SI {
String m(Integer a);
}
class CIA {
String xI(Integer i) {
return "xI:" + i;
}
public class CIB {
public void testMethodReferenceInstance() {
SI q;
q = CIA.this::xI;
assertEquals(q.m(55), "xI:55");
}
public void testMethodReferenceExternal() {
SI q;
q = (new E())::xI;
assertEquals(q.m(77), "ExI:77");
}
}
CIB cib() {
return new CIB();
}
class E {
String xI(Integer i) {
return "ExI:" + i;
}
}
}
CIA cia() {
return new CIA();
}
}

View file

@ -0,0 +1,250 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestInnerVarArgsThis
*/
import org.testng.annotations.Test;
import java.lang.reflect.Array;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
@Test
public class MethodReferenceTestInnerVarArgsThis {
interface NsII {
String m(Integer a, Integer b);
}
interface Nsiii {
String m(int a, int b, int c);
}
interface Nsi {
String m(int a);
}
interface NsaO {
String m(Object[] a);
}
interface Nsai {
String m(int[] a);
}
interface Nsvi {
String m(int... va);
}
class CIA {
String xvI(Integer... vi) {
StringBuilder sb = new StringBuilder("xvI:");
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
String xIvI(Integer f, Integer... vi) {
StringBuilder sb = new StringBuilder("xIvI:");
sb.append(f);
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
String xvi(int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xvi:" + sum;
}
String xIvi(Integer f, int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xIvi:(" + f + ")" + sum;
}
String xvO(Object... vi) {
StringBuilder sb = new StringBuilder("xvO:");
for (Object i : vi) {
if (i.getClass().isArray()) {
sb.append("[");
int len = Array.getLength(i);
for (int x = 0; x < len; ++x) {
sb.append(Array.get(i, x));
sb.append(",");
}
sb.append("]");
} else {
sb.append(i);
}
sb.append("*");
}
return sb.toString();
}
public class CIB {
// These should be processed as var args
public void testVarArgsNsSuperclass() {
NsII q;
q = CIA.this::xvO;
assertEquals(q.m(55, 66), "xvO:55*66*");
}
public void testVarArgsNsArray() {
Nsai q;
q = CIA.this::xvO;
assertEquals(q.m(new int[]{55, 66}), "xvO:[55,66,]*");
}
public void testVarArgsNsII() {
NsII q;
q = CIA.this::xvI;
assertEquals(q.m(33, 7), "xvI:33-7-");
q = CIA.this::xIvI;
assertEquals(q.m(50, 40), "xIvI:5040-");
q = CIA.this::xvi;
assertEquals(q.m(100, 23), "xvi:123");
q = CIA.this::xIvi;
assertEquals(q.m(9, 21), "xIvi:(9)21");
}
public void testVarArgsNsiii() {
Nsiii q;
q = CIA.this::xvI;
assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
q = CIA.this::xIvI;
assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
q = CIA.this::xvi;
assertEquals(q.m(900, 80, 7), "xvi:987");
q = CIA.this::xIvi;
assertEquals(q.m(333, 27, 72), "xIvi:(333)99");
}
public void testVarArgsNsi() {
Nsi q;
q = CIA.this::xvI;
assertEquals(q.m(3), "xvI:3-");
q = CIA.this::xIvI;
assertEquals(q.m(888), "xIvI:888");
q = CIA.this::xvi;
assertEquals(q.m(900), "xvi:900");
q = CIA.this::xIvi;
assertEquals(q.m(333), "xIvi:(333)0");
}
// These should NOT be processed as var args
public void testVarArgsNsaO() {
NsaO q;
q = CIA.this::xvO;
assertEquals(q.m(new String[]{"yo", "there", "dude"}), "xvO:yo*there*dude*");
}
}
CIB cib() {
return new CIB();
}
class E {
String xI(Integer i) {
return "ExI:" + i;
}
}
}
CIA cia() {
return new CIA();
}
// These should be processed as var args
public void testVarArgsNsSuperclass() {
cia().cib().testVarArgsNsSuperclass();
}
public void testVarArgsNsArray() {
cia().cib().testVarArgsNsArray();
}
public void testVarArgsNsII() {
cia().cib().testVarArgsNsII();
}
public void testVarArgsNsiii() {
cia().cib().testVarArgsNsiii();
}
public void testVarArgsNsi() {
cia().cib().testVarArgsNsi();
}
// These should NOT be processed as var args
public void testVarArgsNsaO() {
cia().cib().testVarArgsNsaO();
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestInstance
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
class MethodReferenceTestInstance_E {
String xI(Integer i) {
return "ExI:" + i;
}
}
@Test
public class MethodReferenceTestInstance {
interface SI { String m(Integer a); }
String xI(Integer i) {
return "xI:" + i;
}
public void testMethodReferenceInstance() {
SI q;
q = this::xI;
assertEquals(q.m(55), "xI:55");
}
public void testMethodReferenceExternal() {
SI q;
q = (new MethodReferenceTestInstance_E())::xI;
assertEquals(q.m(77), "ExI:77");
}
}

View file

@ -0,0 +1,194 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestKinds
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
@Test
public class MethodReferenceTestKinds extends MethodReferenceTestKindsSup {
interface S0 { String get(); }
interface S1 { String get(MethodReferenceTestKinds x); }
interface S2 { String get(MethodReferenceTestKinds x, MethodReferenceTestKinds y); }
interface SXN0 { MethodReferenceTestKindsBase make(MethodReferenceTestKinds x); }
interface SXN1 { MethodReferenceTestKindsBase make(MethodReferenceTestKinds x, String str); }
interface SN0 { MethodReferenceTestKindsBase make(); }
interface SN1 { MethodReferenceTestKindsBase make(String x); }
class In extends MethodReferenceTestKindsBase {
In(String val) {
this.val = val;
}
In() {
this("blank");
}
}
String instanceMethod0() { return "IM:0-" + this; }
String instanceMethod1(MethodReferenceTestKinds x) { return "IM:1-" + this + x; }
static String staticMethod0() { return "SM:0"; }
static String staticMethod1(MethodReferenceTestKinds x) { return "SM:1-" + x; }
MethodReferenceTestKinds(String val) {
super(val);
}
MethodReferenceTestKinds() {
super("blank");
}
MethodReferenceTestKinds inst(String val) {
return new MethodReferenceTestKinds(val);
}
public void testMRBound() {
S0 var = this::instanceMethod0;
assertEquals(var.get(), "IM:0-MethodReferenceTestKinds(blank)");
}
public void testMRBoundArg() {
S1 var = this::instanceMethod1;
assertEquals(var.get(inst("arg")), "IM:1-MethodReferenceTestKinds(blank)MethodReferenceTestKinds(arg)");
}
public void testMRUnbound() {
S1 var = MethodReferenceTestKinds::instanceMethod0;
assertEquals(var.get(inst("rcvr")), "IM:0-MethodReferenceTestKinds(rcvr)");
}
public void testMRUnboundArg() {
S2 var = MethodReferenceTestKinds::instanceMethod1;
assertEquals(var.get(inst("rcvr"), inst("arg")), "IM:1-MethodReferenceTestKinds(rcvr)MethodReferenceTestKinds(arg)");
}
public void testMRSuper() {
S0 var = super::instanceMethod0;
assertEquals(var.get(), "SIM:0-MethodReferenceTestKinds(blank)");
}
public void testMRSuperArg() {
S1 var = super::instanceMethod1;
assertEquals(var.get(inst("arg")), "SIM:1-MethodReferenceTestKinds(blank)MethodReferenceTestKinds(arg)");
}
public void testMRStatic() {
S0 var = MethodReferenceTestKinds::staticMethod0;
assertEquals(var.get(), "SM:0");
}
public void testMRStaticArg() {
S1 var = MethodReferenceTestKinds::staticMethod1;
assertEquals(var.get(inst("arg")), "SM:1-MethodReferenceTestKinds(arg)");
}
public void testMRStaticEval() {
MethodReferenceTestKinds evalCheck;
S0 var = (evalCheck = inst("discard"))::staticMethod0;
assertEquals(evalCheck.toString(), "MethodReferenceTestKinds(discard)");
assertEquals(var.get(), "SM:0");
}
public void testMRStaticEvalArg() {
MethodReferenceTestKinds evalCheck;
S1 var = (evalCheck = inst("discard"))::staticMethod1;
assertEquals(evalCheck.toString(), "MethodReferenceTestKinds(discard)");
assertEquals(var.get(inst("arg")), "SM:1-MethodReferenceTestKinds(arg)");
}
public void testMRTopLevel() {
SN0 var = MethodReferenceTestKindsBase::new;
assertEquals(var.make().toString(), "MethodReferenceTestKindsBase(blank)");
}
public void testMRTopLevelArg() {
SN1 var = MethodReferenceTestKindsBase::new;
assertEquals(var.make("name").toString(), "MethodReferenceTestKindsBase(name)");
}
/* unbound inner case not supported anymore (dropped by EG)
public void testMRUnboundInner() {
SXN0 var = MethodReferenceTestKinds.In::new;
assertEquals(var.make(inst("out")).toString(), "In(blank)");
}
public void testMRUnboundInnerArg() {
SXN1 var = MethodReferenceTestKinds.In::new;
assertEquals(var.make(inst("out"), "name").toString(), "In(name)");
}
*/
public void testMRImplicitInner() {
SN0 var = MethodReferenceTestKinds.In::new;
assertEquals(var.make().toString(), "In(blank)");
}
public void testMRImplicitInnerArg() {
SN1 var = MethodReferenceTestKinds.In::new;
assertEquals(var.make("name").toString(), "In(name)");
}
}
class MethodReferenceTestKindsBase {
String val = "unset";
public String toString() {
return getClass().getSimpleName() + "(" + val + ")";
}
MethodReferenceTestKindsBase(String val) {
this.val = val;
}
MethodReferenceTestKindsBase() {
this("blank");
}
}
class MethodReferenceTestKindsSup extends MethodReferenceTestKindsBase {
String instanceMethod0() { return "SIM:0-" + this; }
String instanceMethod1(MethodReferenceTestKinds x) { return "SIM:1-" + this + x; }
MethodReferenceTestKindsSup(String val) {
super(val);
}
}

View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestNew
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
@Test
public class MethodReferenceTestNew {
interface M0<T> {
T m();
}
static class N0 {
N0() {
}
}
interface M1<T> {
T m(Integer a);
}
static class N1 {
int i;
N1(int i) {
this.i = i;
}
}
interface M2<T> {
T m(Integer n, String o);
}
static class N2 {
Number n;
Object o;
N2(Number n, Object o) {
this.n = n;
this.o = o;
}
public String toString() {
return "N2(" + n + "," + o + ")";
}
}
interface MV {
NV m(Integer ai, int i);
}
static class NV {
int i;
NV(int... v) {
i = 0;
for (int x : v) {
i += x;
}
}
public String toString() {
return "NV(" + i + ")";
}
}
public void testConstructorReference0() {
M0<N0> q;
q = N0::new;
assertEquals(q.m().getClass().getSimpleName(), "N0");
}
public void testConstructorReference1() {
M1<N1> q;
q = N1::new;
assertEquals(q.m(14).getClass().getSimpleName(), "N1");
}
public void testConstructorReference2() {
M2<N2> q;
q = N2::new;
assertEquals(q.m(7, "hi").toString(), "N2(7,hi)");
}
public void testConstructorReferenceVarArgs() {
MV q;
q = NV::new;
assertEquals(q.m(5, 45).toString(), "NV(50)");
}
}

View file

@ -0,0 +1,157 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestNewInner
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
@Test
public class MethodReferenceTestNewInner {
String note = "NO NOTE";
interface M0<T> {
T m();
}
interface MP<T> {
T m(MethodReferenceTestNewInner m);
}
class N0 {
N0() {
}
}
interface M1<T> {
T m(Integer a);
}
class N1 {
int i;
N1(int i) {
this.i = i;
}
}
interface M2<T> {
T m(Integer n, String o);
}
class N2 {
Number n;
Object o;
N2(Number n, Object o) {
this.n = n;
this.o = o;
}
public String toString() {
return note + ":N2(" + n + "," + o + ")";
}
}
interface MV {
NV m(Integer ai, int i);
}
class NV {
int i;
NV(int... v) {
i = 0;
for (int x : v) {
i += x;
}
}
public String toString() {
return note + ":NV(" + i + ")";
}
}
/* unbound constructor case not supported anymore (dropped by EG)
public static void testConstructorReferenceP() {
MP<N0> q;
q = N0::new;
assertEquals(q.m(new MethodReferenceTestNewInner()).getClass().getSimpleName(), "N0");
}
*/
public void testConstructorReference0() {
M0<N0> q;
q = N0::new;
assertEquals(q.m().getClass().getSimpleName(), "N0");
}
public void testConstructorReference1() {
M1<N1> q;
q = N1::new;
assertEquals(q.m(14).getClass().getSimpleName(), "N1");
}
public void testConstructorReference2() {
M2<N2> q;
note = "T2";
q = N2::new;
assertEquals(q.m(7, "hi").toString(), "T2:N2(7,hi)");
}
/***
public void testConstructorReferenceVarArgs() {
MV q;
note = "TVA";
q = NV::new;
assertEquals(q.m(5, 45).toString(), "TNV:NV(50)");
}
***/
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestSueCase1
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
@Test
public class MethodReferenceTestSueCase1 {
public interface Sam2<T> { public String get(T target, String s); }
String instanceMethod(String s) { return "2"; }
Sam2<MethodReferenceTestSueCase1> var = MethodReferenceTestSueCase1::instanceMethod;
String m() { return var.get(new MethodReferenceTestSueCase1(), ""); }
public void testSueCase1() {
assertEquals(m(), "2");
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestSueCase2
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
@Test
public class MethodReferenceTestSueCase2 {
public interface Sam2<T> { public String get(T target, String s); }
String instanceMethod(String s) { return "2"; }
static Sam2<MethodReferenceTestSueCase2> var = MethodReferenceTestSueCase2::instanceMethod;
String m() { return var.get(new MethodReferenceTestSueCase2(), ""); }
public void testSueCase2() {
assertEquals(m(), "2");
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestSueCase4
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
@Test
public class MethodReferenceTestSueCase4 {
public interface Sam2<T> { public String get(T target, String s); }
Sam2<Target> var = new Object().equals(new Object()) ? Target::instanceMethod : Target::instanceMethod;
String m() {
return var.get(new Target(), "");
}
static class Target {
String instanceMethod(String s) { return "2"; }
}
public void testSueCase4() {
assertEquals(m(), "2");
}
}

View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestSuper
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
interface SPRI { String m(String a); }
class SPRA {
String xsA__(String s) {
return "A__xsA:" + s;
}
String xsA_M(String s) {
return "A_MxsA:" + s;
}
String xsAB_(String s) {
return "AB_xsA:" + s;
}
String xsABM(String s) {
return "ABMxsA:" + s;
}
}
class SPRB extends SPRA {
String xsAB_(String s) {
return "AB_xsB:" + s;
}
String xsABM(String s) {
return "ABMxsB:" + s;
}
String xs_B_(String s) {
return "_B_xsB:" + s;
}
String xs_BM(String s) {
return "_BMxsB:" + s;
}
}
@Test
public class MethodReferenceTestSuper extends SPRB {
String xsA_M(String s) {
return "A_MxsM:" + s;
}
String xsABM(String s) {
return "ABMxsM:" + s;
}
String xs_BM(String s) {
return "_BMxsM:" + s;
}
public void testMethodReferenceSuper() {
SPRI q;
q = super::xsA__;
assertEquals(q.m("*"), "A__xsA:*");
q = super::xsA_M;
assertEquals(q.m("*"), "A_MxsA:*");
q = super::xsAB_;
assertEquals(q.m("*"), "AB_xsB:*");
q = super::xsABM;
assertEquals(q.m("*"), "ABMxsB:*");
q = super::xs_B_;
assertEquals(q.m("*"), "_B_xsB:*");
q = super::xs_BM;
assertEquals(q.m("*"), "_BMxsB:*");
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestSuperDefault
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
interface DSPRI { String m(String a); }
interface DSPRA {
default String xsA__(String s) {
return "A__xsA:" + s;
}
default String xsAB_(String s) {
return "AB_xsA:" + s;
}
}
interface DSPRB extends DSPRA {
default String xsAB_(String s) {
return "AB_xsB:" + s;
}
default String xs_B_(String s) {
return "_B_xsB:" + s;
}
}
@Test
public class MethodReferenceTestSuperDefault implements DSPRB {
public void testMethodReferenceSuper() {
DSPRI q;
q = DSPRB.super::xsA__;
assertEquals(q.m("*"), "A__xsA:*");
q = DSPRB.super::xsAB_;
assertEquals(q.m("*"), "AB_xsB:*");
q = DSPRB.super::xs_B_;
assertEquals(q.m("*"), "_B_xsB:*");
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestTypeConversion
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
class MethodReferenceTestTypeConversion_E<T> {
T xI(T t) { return t; }
}
@Test
public class MethodReferenceTestTypeConversion {
interface ISi { int m(Short a); }
interface ICc { char m(Character a); }
public void testUnboxObjectToNumberWiden() {
ISi q = (new MethodReferenceTestTypeConversion_E<Short>())::xI;
assertEquals(q.m((short)77), (short)77);
}
public void testUnboxObjectToChar() {
ICc q = (new MethodReferenceTestTypeConversion_E<Character>())::xI;
assertEquals(q.m('@'), '@');
}
}

View file

@ -0,0 +1,204 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestVarArgs
*/
import org.testng.annotations.Test;
import java.lang.reflect.Array;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
@Test
public class MethodReferenceTestVarArgs {
interface SII {
String m(Integer a, Integer b);
}
interface Siii {
String m(int a, int b, int c);
}
interface Si {
String m(int a);
}
interface SaO {
String m(Object[] a);
}
interface Sai {
String m(int[] a);
}
interface Svi {
String m(int... va);
}
// These should be processed as var args
static String xvI(Integer... vi) {
StringBuilder sb = new StringBuilder("xvI:");
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
static String xIvI(Integer f, Integer... vi) {
StringBuilder sb = new StringBuilder("xIvI:");
sb.append(f);
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
static String xvi(int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xvi:" + sum;
}
static String xIvi(Integer f, int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xIvi:(" + f + ")" + sum;
}
static String xvO(Object... vi) {
StringBuilder sb = new StringBuilder("xvO:");
for (Object i : vi) {
if (i.getClass().isArray()) {
sb.append("[");
int len = Array.getLength(i);
for (int x = 0; x < len; ++x) {
sb.append(Array.get(i, x));
sb.append(",");
}
sb.append("]");
} else {
sb.append(i);
}
sb.append("*");
}
return sb.toString();
}
public void testVarArgsSuperclass() {
SII q;
q = MethodReferenceTestVarArgs::xvO;
assertEquals(q.m(55,66), "xvO:55*66*");
}
public void testVarArgsArray() {
Sai q;
q = MethodReferenceTestVarArgs::xvO;
assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
}
public void testVarArgsII() {
SII q;
q = MethodReferenceTestVarArgs::xvI;
assertEquals(q.m(33,7), "xvI:33-7-");
q = MethodReferenceTestVarArgs::xIvI;
assertEquals(q.m(50,40), "xIvI:5040-");
q = MethodReferenceTestVarArgs::xvi;
assertEquals(q.m(100,23), "xvi:123");
q = MethodReferenceTestVarArgs::xIvi;
assertEquals(q.m(9,21), "xIvi:(9)21");
}
public void testVarArgsiii() {
Siii q;
q = MethodReferenceTestVarArgs::xvI;
assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
q = MethodReferenceTestVarArgs::xIvI;
assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
q = MethodReferenceTestVarArgs::xvi;
assertEquals(q.m(900,80,7), "xvi:987");
q = MethodReferenceTestVarArgs::xIvi;
assertEquals(q.m(333,27, 72), "xIvi:(333)99");
}
public void testVarArgsi() {
Si q;
q = MethodReferenceTestVarArgs::xvI;
assertEquals(q.m(3), "xvI:3-");
q = MethodReferenceTestVarArgs::xIvI;
assertEquals(q.m(888), "xIvI:888");
q = MethodReferenceTestVarArgs::xvi;
assertEquals(q.m(900), "xvi:900");
q = MethodReferenceTestVarArgs::xIvi;
assertEquals(q.m(333), "xIvi:(333)0");
}
// These should NOT be processed as var args
public void testVarArgsaO() {
SaO q;
q = MethodReferenceTestVarArgs::xvO;
assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
}
}

View file

@ -0,0 +1,191 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestVarArgsExt
*/
import org.testng.annotations.Test;
import java.lang.reflect.Array;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
interface NXII { String m(Integer a, Integer b); }
interface NXiii { String m(int a, int b, int c); }
interface NXi { String m(int a); }
interface NXaO { String m(Object[] a); }
interface NXai { String m(int[] a); }
interface NXvi { String m(int... va); }
@Test
public class MethodReferenceTestVarArgsExt {
// These should be processed as var args
public void testVarArgsNXSuperclass() {
NXII q;
q = (new Ext())::xvO;
assertEquals(q.m(55,66), "xvO:55*66*");
}
public void testVarArgsNXArray() {
NXai q;
q = (new Ext())::xvO;
assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
}
public void testVarArgsNXII() {
NXII q;
q = (new Ext())::xvI;
assertEquals(q.m(33,7), "xvI:33-7-");
q = (new Ext())::xIvI;
assertEquals(q.m(50,40), "xIvI:5040-");
q = (new Ext())::xvi;
assertEquals(q.m(100,23), "xvi:123");
q = (new Ext())::xIvi;
assertEquals(q.m(9,21), "xIvi:(9)21");
}
public void testVarArgsNXiii() {
NXiii q;
q = (new Ext())::xvI;
assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
q = (new Ext())::xIvI;
assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
q = (new Ext())::xvi;
assertEquals(q.m(900,80,7), "xvi:987");
q = (new Ext())::xIvi;
assertEquals(q.m(333,27, 72), "xIvi:(333)99");
}
public void testVarArgsNXi() {
NXi q;
q = (new Ext())::xvI;
assertEquals(q.m(3), "xvI:3-");
q = (new Ext())::xIvI;
assertEquals(q.m(888), "xIvI:888");
q = (new Ext())::xvi;
assertEquals(q.m(900), "xvi:900");
q = (new Ext())::xIvi;
assertEquals(q.m(333), "xIvi:(333)0");
}
// These should NOT be processed as var args
public void testVarArgsNXaO() {
NXaO q;
q = (new Ext())::xvO;
assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
}
}
class Ext {
String xvI(Integer... vi) {
StringBuilder sb = new StringBuilder("xvI:");
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
String xIvI(Integer f, Integer... vi) {
StringBuilder sb = new StringBuilder("xIvI:");
sb.append(f);
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
String xvi(int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xvi:" + sum;
}
String xIvi(Integer f, int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xIvi:(" + f + ")" + sum;
}
String xvO(Object... vi) {
StringBuilder sb = new StringBuilder("xvO:");
for (Object i : vi) {
if (i.getClass().isArray()) {
sb.append("[");
int len = Array.getLength(i);
for (int x = 0; x < len; ++x) {
sb.append(Array.get(i, x));
sb.append(",");
}
sb.append("]");
} else {
sb.append(i);
}
sb.append("*");
}
return sb.toString();
}
}

View file

@ -0,0 +1,207 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestVarArgsSuper
*/
import org.testng.annotations.Test;
import java.lang.reflect.Array;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
class MethodReferenceTestVarArgsSuper_Sub {
String xvI(Integer... vi) {
StringBuilder sb = new StringBuilder("xvI:");
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
String xIvI(Integer f, Integer... vi) {
StringBuilder sb = new StringBuilder("xIvI:");
sb.append(f);
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
String xvi(int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xvi:" + sum;
}
String xIvi(Integer f, int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xIvi:(" + f + ")" + sum;
}
String xvO(Object... vi) {
StringBuilder sb = new StringBuilder("xvO:");
for (Object i : vi) {
if (i.getClass().isArray()) {
sb.append("[");
int len = Array.getLength(i);
for (int x = 0; x < len; ++x) {
sb.append(Array.get(i, x));
sb.append(",");
}
sb.append("]");
} else {
sb.append(i);
}
sb.append("*");
}
return sb.toString();
}
}
@Test
public class MethodReferenceTestVarArgsSuper extends MethodReferenceTestVarArgsSuper_Sub {
interface SPRII { String m(Integer a, Integer b); }
interface SPRiii { String m(int a, int b, int c); }
interface SPRi { String m(int a); }
interface SPRaO { String m(Object[] a); }
interface SPRai { String m(int[] a); }
interface SPRvi { String m(int... va); }
String xvI(Integer... vi) {
return "ERROR";
}
String xIvI(Integer f, Integer... vi) {
return "ERROR";
}
String xvi(int... vi) {
return "ERROR";
}
String xIvi(Integer f, int... vi) {
return "ERROR";
}
String xvO(Object... vi) {
return "ERROR";
}
// These should be processed as var args
public void testVarArgsSPRSuperclass() {
SPRII q;
q = super::xvO;
assertEquals(q.m(55,66), "xvO:55*66*");
}
public void testVarArgsSPRArray() {
SPRai q;
q = super::xvO;
assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
}
public void testVarArgsSPRII() {
SPRII q;
q = super::xvI;
assertEquals(q.m(33,7), "xvI:33-7-");
q = super::xIvI;
assertEquals(q.m(50,40), "xIvI:5040-");
q = super::xvi;
assertEquals(q.m(100,23), "xvi:123");
q = super::xIvi;
assertEquals(q.m(9,21), "xIvi:(9)21");
}
public void testVarArgsSPRiii() {
SPRiii q;
q = super::xvI;
assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
q = super::xIvI;
assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
q = super::xvi;
assertEquals(q.m(900,80,7), "xvi:987");
q = super::xIvi;
assertEquals(q.m(333,27, 72), "xIvi:(333)99");
}
public void testVarArgsSPRi() {
SPRi q;
q = super::xvI;
assertEquals(q.m(3), "xvI:3-");
q = super::xIvI;
assertEquals(q.m(888), "xIvI:888");
q = super::xvi;
assertEquals(q.m(900), "xvi:900");
q = super::xIvi;
assertEquals(q.m(333), "xIvi:(333)0");
}
// These should NOT be processed as var args
public void testVarArgsSPRaO() {
SPRaO q;
q = super::xvO;
assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
}
}

View file

@ -0,0 +1,189 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestVarArgsSuperDefault
*/
import org.testng.annotations.Test;
import java.lang.reflect.Array;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
interface MethodReferenceTestVarArgsSuperDefault_I {
default String xvI(Integer... vi) {
StringBuilder sb = new StringBuilder("xvI:");
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
default String xIvI(Integer f, Integer... vi) {
StringBuilder sb = new StringBuilder("xIvI:");
sb.append(f);
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
default String xvi(int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xvi:" + sum;
}
default String xIvi(Integer f, int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xIvi:(" + f + ")" + sum;
}
default String xvO(Object... vi) {
StringBuilder sb = new StringBuilder("xvO:");
for (Object i : vi) {
if (i.getClass().isArray()) {
sb.append("[");
int len = Array.getLength(i);
for (int x = 0; x < len; ++x) {
sb.append(Array.get(i, x));
sb.append(",");
}
sb.append("]");
} else {
sb.append(i);
}
sb.append("*");
}
return sb.toString();
}
}
@Test
public class MethodReferenceTestVarArgsSuperDefault implements MethodReferenceTestVarArgsSuperDefault_I {
interface DSPRII { String m(Integer a, Integer b); }
interface DSPRiii { String m(int a, int b, int c); }
interface DSPRi { String m(int a); }
interface DSPRaO { String m(Object[] a); }
interface DSPRai { String m(int[] a); }
interface DSPRvi { String m(int... va); }
// These should be processed as var args
public void testVarArgsSPRSuperclass() {
DSPRII q;
q = MethodReferenceTestVarArgsSuperDefault_I.super::xvO;
assertEquals(q.m(55,66), "xvO:55*66*");
}
public void testVarArgsSPRArray() {
DSPRai q;
q = MethodReferenceTestVarArgsSuperDefault_I.super::xvO;
assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
}
public void testVarArgsSPRII() {
DSPRII q;
q = MethodReferenceTestVarArgsSuperDefault_I.super::xvI;
assertEquals(q.m(33,7), "xvI:33-7-");
q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvI;
assertEquals(q.m(50,40), "xIvI:5040-");
q = MethodReferenceTestVarArgsSuperDefault_I.super::xvi;
assertEquals(q.m(100,23), "xvi:123");
q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvi;
assertEquals(q.m(9,21), "xIvi:(9)21");
}
public void testVarArgsSPRiii() {
DSPRiii q;
q = MethodReferenceTestVarArgsSuperDefault_I.super::xvI;
assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvI;
assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
q = MethodReferenceTestVarArgsSuperDefault_I.super::xvi;
assertEquals(q.m(900,80,7), "xvi:987");
q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvi;
assertEquals(q.m(333,27, 72), "xIvi:(333)99");
}
public void testVarArgsSPRi() {
DSPRi q;
q = MethodReferenceTestVarArgsSuperDefault_I.super::xvI;
assertEquals(q.m(3), "xvI:3-");
q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvI;
assertEquals(q.m(888), "xIvI:888");
q = MethodReferenceTestVarArgsSuperDefault_I.super::xvi;
assertEquals(q.m(900), "xvi:900");
q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvi;
assertEquals(q.m(333), "xIvi:(333)0");
}
// These should NOT be processed as var args
public void testVarArgsSPRaO() {
DSPRaO q;
q = MethodReferenceTestVarArgsSuperDefault_I.super::xvO;
assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
}
}

View file

@ -0,0 +1,186 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng MethodReferenceTestVarArgsThis
*/
import org.testng.annotations.Test;
import java.lang.reflect.Array;
import static org.testng.Assert.assertEquals;
/**
* @author Robert Field
*/
interface NsII { String m(Integer a, Integer b); }
interface Nsiii { String m(int a, int b, int c); }
interface Nsi { String m(int a); }
interface NsaO { String m(Object[] a); }
interface Nsai { String m(int[] a); }
interface Nsvi { String m(int... va); }
@Test
public class MethodReferenceTestVarArgsThis {
// These should be processed as var args
String xvI(Integer... vi) {
StringBuilder sb = new StringBuilder("xvI:");
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
String xIvI(Integer f, Integer... vi) {
StringBuilder sb = new StringBuilder("xIvI:");
sb.append(f);
for (Integer i : vi) {
sb.append(i);
sb.append("-");
}
return sb.toString();
}
String xvi(int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xvi:" + sum;
}
String xIvi(Integer f, int... vi) {
int sum = 0;
for (int i : vi) {
sum += i;
}
return "xIvi:(" + f + ")" + sum;
}
String xvO(Object... vi) {
StringBuilder sb = new StringBuilder("xvO:");
for (Object i : vi) {
if (i.getClass().isArray()) {
sb.append("[");
int len = Array.getLength(i);
for (int x = 0; x < len; ++x) {
sb.append(Array.get(i, x));
sb.append(",");
}
sb.append("]");
} else {
sb.append(i);
}
sb.append("*");
}
return sb.toString();
}
public void testVarArgsNsSuperclass() {
NsII q;
q = this::xvO;
assertEquals(q.m(55,66), "xvO:55*66*");
}
public void testVarArgsNsArray() {
Nsai q;
q = this::xvO;
assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
}
public void testVarArgsNsII() {
NsII q;
q = this::xvI;
assertEquals(q.m(33,7), "xvI:33-7-");
q = this::xIvI;
assertEquals(q.m(50,40), "xIvI:5040-");
q = this::xvi;
assertEquals(q.m(100,23), "xvi:123");
q = this::xIvi;
assertEquals(q.m(9,21), "xIvi:(9)21");
}
public void testVarArgsNsiii() {
Nsiii q;
q = this::xvI;
assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
q = this::xIvI;
assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
q = this::xvi;
assertEquals(q.m(900,80,7), "xvi:987");
q = this::xIvi;
assertEquals(q.m(333,27, 72), "xIvi:(333)99");
}
public void testVarArgsNsi() {
Nsi q;
q = this::xvI;
assertEquals(q.m(3), "xvI:3-");
q = this::xIvI;
assertEquals(q.m(888), "xIvI:888");
q = this::xvi;
assertEquals(q.m(900), "xvi:900");
q = this::xIvi;
assertEquals(q.m(333), "xIvi:(333)0");
}
// These should NOT be processed as var args
public void testVarArgsNsaO() {
NsaO q;
q = this::xvO;
assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
}
}

View file

@ -0,0 +1,2 @@
TestNG.dirs = tools/javac/lambdaShapes

View file

@ -21,14 +21,12 @@
* questions.
*/
/*
* @test
* @summary Automatic test for checking correctness of default resolution
*/
package org.openjdk.tests.javac;
import shapegen.*;
import org.openjdk.tests.shapegen.*;
import com.sun.source.util.JavacTask;
import com.sun.tools.javac.util.Pair;
import java.net.URI;
import java.util.Arrays;
@ -43,9 +41,14 @@ import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.DataProvider;
import static org.testng.Assert.*;
public class FDTest {
enum TestKind {
public enum TestKind {
POSITIVE,
NEGATIVE;
@ -55,24 +58,67 @@ public class FDTest {
}
}
public static void main(String[] args) throws Exception {
//create default shared JavaCompiler - reused across multiple compilations
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
public static JavaCompiler comp;
public static StandardJavaFileManager fm;
@BeforeSuite
static void init() {
// create default shared JavaCompiler - reused across multiple
// compilations
comp = ToolProvider.getSystemJavaCompiler();
fm = comp.getStandardFileManager(null, null, null);
}
public static void main(String[] args) throws Exception {
init();
for (Pair<TestKind,Hierarchy> fdtest : generateCases()) {
runTest(fdtest.fst, fdtest.snd, comp, fm);
}
}
@Test(dataProvider = "fdCases")
public void testOneCase(TestKind tk, Hierarchy hs)
throws Exception {
FDTest.runTest(tk, hs, comp, fm);
}
@DataProvider(name = "fdCases")
public Object[][] caseGenerator() {
List<Pair<TestKind, Hierarchy>> cases = generateCases();
Object[][] fdCases = new Object[cases.size()][];
for (int i = 0; i < cases.size(); ++i) {
fdCases[i] = new Object[2];
fdCases[i][0] = cases.get(i).fst;
fdCases[i][1] = cases.get(i).snd;
}
return fdCases;
}
public static List<Pair<TestKind, Hierarchy>> generateCases() {
ArrayList<Pair<TestKind,Hierarchy>> list = new ArrayList<>();
HierarchyGenerator hg = new HierarchyGenerator();
for (TestKind tk : TestKind.values()) {
for (Hierarchy hs : tk.getHierarchy(hg)) {
list.add(new Pair<>(tk, hs));
}
}
return list;
}
public static void runTest(TestKind tk, Hierarchy hs,
JavaCompiler comp, StandardJavaFileManager fm) throws Exception {
new FDTest(tk, hs).run(comp, fm);
}
}
}
TestKind tk;
Hierarchy hs;
DefenderTestSource source;
DiagnosticChecker diagChecker;
public FDTest() {}
FDTest(TestKind tk, Hierarchy hs) {
this.tk = tk;
this.hs = hs;
@ -86,7 +132,7 @@ public class FDTest {
try {
ct.analyze();
} catch (Throwable ex) {
throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
fail("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
}
check();
}
@ -94,7 +140,7 @@ public class FDTest {
void check() {
boolean errorExpected = tk == TestKind.NEGATIVE;
if (errorExpected != diagChecker.errorFound) {
throw new AssertionError("problem in source: \n" +
fail("problem in source: \n" +
"\nerror found = " + diagChecker.errorFound +
"\nerror expected = " + errorExpected +
"\n" + dumpHierarchy() +
@ -123,7 +169,7 @@ public class FDTest {
StringBuilder buf = new StringBuilder();
List<ClassCase> defaultRef = new ArrayList<>();
for (ClassCase cc : hs.all) {
hs.genClassDef(buf, cc, null, defaultRef);
Hierarchy.genClassDef(buf, cc, null, defaultRef);
}
source = buf.toString();
}

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package org.openjdk.tests.separate;
import java.io.*;
public class AttributeInjector implements ClassFilePreprocessor {
private String attributeName;
private byte[] attributeData;
public AttributeInjector(String attributeName, byte[] attributeData) {
this.attributeName = attributeName;
this.attributeData = attributeData;
}
public byte[] preprocess(String name, byte[] cf) {
ClassFile classfile = new ClassFile(cf);
short cpIndex = (short)classfile.constant_pool.size();
ClassFile.CpUtf8 entry = new ClassFile.CpUtf8();
entry.bytes = new byte[attributeName.length()];
for (int i = 0; i < attributeName.length(); ++i) {
entry.bytes[i] = (byte)attributeName.charAt(i);
}
classfile.constant_pool.add(entry);
ClassFile.Attribute attr = new ClassFile.Attribute();
attr.attribute_name_index = cpIndex;
attr.info = attributeData;
classfile.attributes.add(attr);
return classfile.toByteArray();
}
/*
public static void main(String argv[]) throws Exception {
File input = new File(argv[0]);
byte[] buffer = new byte[(int)input.length()];
new FileInputStream(input).read(buffer);
ClassFilePreprocessor cfp =
new AttributeInjector("RequiresBridges", new byte[0]);
byte[] cf = cfp.preprocess(argv[0], buffer);
new FileOutputStream(argv[0] + ".mod").write(cf);
}
*/
}

View file

@ -0,0 +1,454 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package org.openjdk.tests.separate;
import java.io.*;
import java.util.*;
class CfInputStream extends ByteArrayInputStream {
private int ct;
public CfInputStream(byte[] input) {
super(input);
}
byte u1() { return (byte)read(); }
short u2() {
int b0 = read() << 8;
int b1 = read();
return (short)(b0 | b1);
}
int u4() {
int b0 = read() << 24;
int b1 = read() << 16;
int b2 = read() << 8;
int b3 = read();
return b0 | b1 | b2 | b3;
}
byte[] array(int count) {
byte[] ret = new byte[count];
read(ret, 0, count);
return ret;
}
};
class CfOutputStream extends ByteArrayOutputStream {
void u1(byte b) { write((int)b); }
void u2(short s) {
write((s >> 8) & 0xff);
write(s & 0xff);
}
void u4(int i) {
write((i >> 24) & 0xff);
write((i >> 16) & 0xff);
write((i >> 8) & 0xff);
write(i & 0xff);
}
void array(byte[] a) {
write(a, 0, a.length);
}
public byte[] toByteArray() { return super.toByteArray(); }
};
// A quick and dirty class file parser and representation
public class ClassFile {
int magic;
short minor_version;
short major_version;
ArrayList<CpEntry> constant_pool;
short access_flags;
short this_class;
short super_class;
ArrayList<Interface> interfaces;
ArrayList<Field> fields;
ArrayList<Method> methods;
ArrayList<Attribute> attributes;
ClassFile(byte[] cf) {
CfInputStream in = new CfInputStream(cf);
magic = in.u4();
minor_version = in.u2();
major_version = in.u2();
short cpCount = in.u2();
constant_pool = new ArrayList<>();
constant_pool.add(new CpNull());
for (int i = 1; i < cpCount; ++i) {
constant_pool.add(CpEntry.newCpEntry(in));
}
access_flags = in.u2();
this_class = in.u2();
super_class = in.u2();
short ifaceCount = in.u2();
interfaces = new ArrayList<>();
for (int i = 0; i < ifaceCount; ++i) {
interfaces.add(new Interface(in));
}
short fieldCount = in.u2();
fields = new ArrayList<>();
for (int i = 0; i < fieldCount; ++i) {
fields.add(new Field(in));
}
short methodCount = in.u2();
methods = new ArrayList<>();
for (int i = 0; i < methodCount; ++i) {
methods.add(new Method(in));
}
short attributeCount = in.u2();
attributes = new ArrayList<>();
for (int i = 0; i < attributeCount; ++i) {
attributes.add(new Attribute(in));
}
}
byte[] toByteArray() {
CfOutputStream out = new CfOutputStream();
out.u4(magic);
out.u2(minor_version);
out.u2(major_version);
out.u2((short)(constant_pool.size()));
for (CpEntry cp : constant_pool) {
cp.write(out);
}
out.u2(access_flags);
out.u2(this_class);
out.u2(super_class);
out.u2((short)interfaces.size());
for (Interface iface : interfaces) {
iface.write(out);
}
out.u2((short)fields.size());
for (Field field : fields) {
field.write(out);
}
out.u2((short)methods.size());
for (Method method : methods) {
method.write(out);
}
out.u2((short)attributes.size());
for (Attribute attribute : attributes) {
attribute.write(out);
}
return out.toByteArray();
}
static abstract class CpEntry {
byte tag;
CpEntry(byte t) { tag = t; }
void write(CfOutputStream out) {
out.u1(tag);
}
static CpEntry newCpEntry(CfInputStream in) {
byte tag = in.u1();
switch (tag) {
case CpUtf8.TAG: return new CpUtf8(in);
case CpInteger.TAG: return new CpInteger(in);
case CpFloat.TAG: return new CpFloat(in);
case CpLong.TAG: return new CpLong(in);
case CpDouble.TAG: return new CpDouble(in);
case CpClass.TAG: return new CpClass(in);
case CpString.TAG: return new CpString(in);
case CpFieldRef.TAG: return new CpFieldRef(in);
case CpMethodRef.TAG: return new CpMethodRef(in);
case CpInterfaceMethodRef.TAG:
return new CpInterfaceMethodRef(in);
case CpNameAndType.TAG: return new CpNameAndType(in);
case CpMethodHandle.TAG: return new CpMethodHandle(in);
case CpMethodType.TAG: return new CpMethodType(in);
case CpInvokeDynamic.TAG: return new CpInvokeDynamic(in);
default: throw new RuntimeException("Bad cp entry tag: " + tag);
}
}
}
static class CpNull extends CpEntry {
CpNull() { super((byte)0); }
CpNull(CfInputStream in) { super((byte)0); }
void write(CfOutputStream out) {}
}
static class CpUtf8 extends CpEntry {
static final byte TAG = 1;
byte[] bytes;
CpUtf8() { super(TAG); }
CpUtf8(CfInputStream in) {
this();
short length = in.u2();
bytes = in.array(length);
}
void write(CfOutputStream out) {
super.write(out);
out.u2((short)bytes.length);
out.array(bytes);
}
}
static class CpU4Constant extends CpEntry {
byte[] bytes;
CpU4Constant(byte tag) { super(tag); }
CpU4Constant(byte tag, CfInputStream in) {
this(tag);
bytes = in.array(4);
}
void write(CfOutputStream out) { super.write(out); out.array(bytes); }
}
static class CpInteger extends CpU4Constant {
static final byte TAG = 3;
CpInteger() { super(TAG); }
CpInteger(CfInputStream in) { super(TAG, in); }
}
static class CpFloat extends CpU4Constant {
static final byte TAG = 4;
CpFloat() { super(TAG); }
CpFloat(CfInputStream in) { super(TAG, in); }
}
static class CpU8Constant extends CpEntry {
byte[] bytes;
CpU8Constant(byte tag) { super(tag); }
CpU8Constant(byte tag, CfInputStream in) {
this(tag);
bytes = in.array(8);
}
void write(CfOutputStream out) { super.write(out); out.array(bytes); }
}
static class CpLong extends CpU8Constant {
static final byte TAG = 5;
CpLong() { super(TAG); }
CpLong(CfInputStream in) { super(TAG, in); }
}
static class CpDouble extends CpU8Constant {
static final byte TAG = 6;
CpDouble() { super(TAG); }
CpDouble(CfInputStream in) { super(TAG, in); }
}
static class CpClass extends CpEntry {
static final byte TAG = 7;
short name_index;
CpClass() { super(TAG); }
CpClass(CfInputStream in) { super(TAG); name_index = in.u2(); }
void write(CfOutputStream out) {
super.write(out);
out.u2(name_index);
}
}
static class CpString extends CpEntry {
static final byte TAG = 8;
short string_index;
CpString() { super(TAG); }
CpString(CfInputStream in) { super(TAG); string_index = in.u2(); }
void write(CfOutputStream out) {
super.write(out);
out.u2(string_index);
}
}
static class CpRef extends CpEntry {
short class_index;
short name_and_type_index;
CpRef(byte tag) { super(tag); }
CpRef(byte tag, CfInputStream in) {
this(tag);
class_index = in.u2();
name_and_type_index = in.u2();
}
void write(CfOutputStream out) {
super.write(out);
out.u2(class_index);
out.u2(name_and_type_index);
}
}
static class CpFieldRef extends CpRef {
static final byte TAG = 9;
CpFieldRef() { super(TAG); }
CpFieldRef(CfInputStream in) { super(TAG, in); }
}
static class CpMethodRef extends CpRef {
static final byte TAG = 10;
CpMethodRef() { super(TAG); }
CpMethodRef(CfInputStream in) { super(TAG, in); }
}
static class CpInterfaceMethodRef extends CpRef {
static final byte TAG = 11;
CpInterfaceMethodRef() { super(TAG); }
CpInterfaceMethodRef(CfInputStream in) { super(TAG, in); }
}
static class CpNameAndType extends CpEntry {
static final byte TAG = 12;
short name_index;
short descriptor_index;
CpNameAndType() { super(TAG); }
CpNameAndType(CfInputStream in) {
this();
name_index = in.u2();
descriptor_index = in.u2();
}
void write(CfOutputStream out) {
super.write(out);
out.u2(name_index);
out.u2(descriptor_index);
}
}
static class CpMethodHandle extends CpEntry {
static final byte TAG = 15;
byte reference_kind;
short reference_index;
CpMethodHandle() { super(TAG); }
CpMethodHandle(CfInputStream in) {
this();
reference_kind = in.u1();
reference_index = in.u2();
}
void write(CfOutputStream out) {
super.write(out);
out.u1(reference_kind);
out.u2(reference_index);
}
}
static class CpMethodType extends CpEntry {
static final byte TAG = 16;
short descriptor_index;
CpMethodType() { super(TAG); }
CpMethodType(CfInputStream in) {
this();
descriptor_index = in.u2();
}
void write(CfOutputStream out) {
super.write(out);
out.u2(descriptor_index);
}
}
static class CpInvokeDynamic extends CpEntry {
static final byte TAG = 18;
short bootstrap_index;
short name_and_type_index;
CpInvokeDynamic() { super(TAG); }
CpInvokeDynamic(CfInputStream in) {
this();
bootstrap_index = in.u2();
name_and_type_index = in.u2();
}
void write(CfOutputStream out) {
super.write(out);
out.u2(bootstrap_index);
out.u2(name_and_type_index);
}
}
static class Interface {
short index;
Interface() {}
Interface(CfInputStream in) { index = in.u2(); }
void write(CfOutputStream out) { out.u2(index); }
}
static class FieldOrMethod {
short access_flags;
short name_index;
short descriptor_index;
ArrayList<Attribute> attributes;
FieldOrMethod() { attributes = new ArrayList<>(); }
FieldOrMethod(CfInputStream in) {
access_flags = in.u2();
name_index = in.u2();
descriptor_index = in.u2();
short attrCount = in.u2();
attributes = new ArrayList<>();
for (int i = 0; i < attrCount; ++i) {
attributes.add(new Attribute(in));
}
}
void write(CfOutputStream out) {
out.u2(access_flags);
out.u2(name_index);
out.u2(descriptor_index);
out.u2((short)attributes.size());
for (Attribute attribute : attributes) { attribute.write(out); }
}
}
static class Field extends FieldOrMethod {
Field() {}
Field(CfInputStream in) { super(in); }
}
static class Method extends FieldOrMethod {
Method() {}
Method(CfInputStream in) { super(in); }
}
static class Attribute {
short attribute_name_index;
byte[] info;
Attribute() { info = new byte[0]; }
Attribute(CfInputStream in) {
attribute_name_index = in.u2();
int length = in.u4();
info = in.array(length);
}
void write(CfOutputStream out) {
out.u2(attribute_name_index);
out.u4(info.length);
out.array(info);
}
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package org.openjdk.tests.separate;
public interface ClassFilePreprocessor {
public byte[] preprocess(String name, byte[] classfile);
};

View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package org.openjdk.tests.separate;
import java.io.*;
import java.util.*;
public class ClassToInterfaceConverter implements ClassFilePreprocessor {
private String whichClass;
public ClassToInterfaceConverter(String className) {
this.whichClass = className;
}
private boolean utf8Matches(ClassFile.CpEntry entry, String v) {
if (!(entry instanceof ClassFile.CpUtf8)) {
return false;
}
ClassFile.CpUtf8 utf8 = (ClassFile.CpUtf8)entry;
if (v.length() != utf8.bytes.length) {
return false;
}
for (int i = 0; i < v.length(); ++i) {
if (v.charAt(i) != utf8.bytes[i]) {
return false;
}
}
return true;
}
private void convertToInterface(ClassFile cf) {
cf.access_flags = 0x0601; // ACC_INTERFACE | ACC_ABSTRACT | ACC_PUBLIC
ArrayList<ClassFile.Method> new_methods = new ArrayList<>();
// Find <init> method and delete it
for (int i = 0; i < cf.methods.size(); ++i) {
ClassFile.Method method = cf.methods.get(i);
ClassFile.CpEntry name = cf.constant_pool.get(method.name_index);
if (!utf8Matches(name, "<init>")) {
new_methods.add(method);
}
}
cf.methods = new_methods;
}
public byte[] preprocess(String classname, byte[] bytes) {
ClassFile cf = new ClassFile(bytes);
ClassFile.CpEntry entry = cf.constant_pool.get(cf.this_class);
ClassFile.CpEntry name = cf.constant_pool.get(
((ClassFile.CpClass)entry).name_index);
if (utf8Matches(name, whichClass)) {
convertToInterface(cf);
return cf.toByteArray();
} else {
return bytes; // unmodified
}
}
/*
public static void main(String argv[]) throws Exception {
File input = new File(argv[0]);
byte[] buffer = new byte[(int)input.length()];
new FileInputStream(input).read(buffer);
ClassFilePreprocessor cfp = new ClassToInterfaceConverter("Hello");
byte[] cf = cfp.preprocess(argv[0], buffer);
new FileOutputStream(argv[0] + ".mod").write(cf);
}
*/
}

View file

@ -0,0 +1,232 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package org.openjdk.tests.separate;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.ConcurrentHashMap;
import java.io.*;
import java.net.URI;
import javax.tools.*;
import com.sun.source.util.JavacTask;
import static org.openjdk.tests.separate.SourceModel.Type;
import static org.openjdk.tests.separate.SourceModel.Class;
import static org.openjdk.tests.separate.SourceModel.Extends;
import static org.openjdk.tests.separate.SourceModel.SourceProcessor;
public class Compiler {
public enum Flags {
VERBOSE, // Prints out files as they are compiled
USECACHE // Keeps results around for reuse. Only use this is
// you're sure that each compilation name maps to the
// same source code
};
private static final AtomicInteger counter = new AtomicInteger();
private static final String targetDir = "gen-separate";
private static final File root = new File(targetDir);
private static ConcurrentHashMap<String,File> cache =
new ConcurrentHashMap<>();
Set<Flags> flags;
private JavaCompiler systemJavaCompiler;
private StandardJavaFileManager fm;
private List<File> tempDirs;
private List<ClassFilePreprocessor> postprocessors;
private static class SourceFile extends SimpleJavaFileObject {
private final String content;
public SourceFile(String name, String content) {
super(URI.create("myfo:/" + name + ".java"), Kind.SOURCE);
this.content = content;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return toString();
}
public String toString() { return this.content; }
}
public Compiler(Flags ... flags) {
setFlags(flags);
this.tempDirs = new ArrayList<>();
this.postprocessors = new ArrayList<>();
this.systemJavaCompiler = ToolProvider.getSystemJavaCompiler();
this.fm = systemJavaCompiler.getStandardFileManager(null, null, null);
}
public void setFlags(Flags ... flags) {
this.flags = new HashSet<Flags>(Arrays.asList(flags));
}
public void addPostprocessor(ClassFilePreprocessor cfp) {
this.postprocessors.add(cfp);
}
/**
* Compile hierarchies starting with each of the 'types' and return
* a ClassLoader that can be used to load the compiled classes.
*/
public ClassLoader compile(Type ... types) {
ClassFilePreprocessor[] cfps = this.postprocessors.toArray(
new ClassFilePreprocessor[0]);
DirectedClassLoader dcl = new DirectedClassLoader(cfps);
for (Type t : types) {
for (Map.Entry<String,File> each : compileHierarchy(t).entrySet()) {
dcl.setLocationFor(each.getKey(), each.getValue());
}
}
return dcl;
}
/**
* Compiles and loads a hierarchy, starting at 'type'
*/
public java.lang.Class<?> compileAndLoad(Type type)
throws ClassNotFoundException {
ClassLoader loader = compile(type);
return java.lang.Class.forName(type.getName(), false, loader);
}
/**
* Compiles a hierarchy, starting at 'type' and return a mapping of the
* name to the location where the classfile for that type resides.
*/
private Map<String,File> compileHierarchy(Type type) {
HashMap<String,File> outputDirs = new HashMap<>();
File outDir = compileOne(type);
outputDirs.put(type.getName(), outDir);
Class superClass = type.getSuperclass();
if (superClass != null) {
for( Map.Entry<String,File> each : compileHierarchy(superClass).entrySet()) {
outputDirs.put(each.getKey(), each.getValue());
}
}
for (Extends ext : type.getSupertypes()) {
Type iface = ext.getType();
for( Map.Entry<String,File> each : compileHierarchy(iface).entrySet()) {
outputDirs.put(each.getKey(), each.getValue());
}
}
return outputDirs;
}
private File compileOne(Type type) {
if (this.flags.contains(Flags.USECACHE)) {
File dir = cache.get(type.getName());
if (dir != null) {
return dir;
}
}
List<JavaFileObject> files = new ArrayList<>();
SourceProcessor accum =
(name, src) -> { files.add(new SourceFile(name, src)); };
for (Type dep : type.typeDependencies()) {
dep.generateAsDependency(accum, type.methodDependencies());
}
type.generate(accum);
JavacTask ct = (JavacTask)this.systemJavaCompiler.getTask(
null, this.fm, null, null, null, files);
File destDir = null;
do {
int value = counter.incrementAndGet();
destDir = new File(root, Integer.toString(value));
} while (destDir.exists());
if (this.flags.contains(Flags.VERBOSE)) {
System.out.println("Compilation unit for " + type.getName() +
" : compiled into " + destDir);
for (JavaFileObject jfo : files) {
System.out.println(jfo.toString());
}
}
try {
destDir.mkdirs();
this.fm.setLocation(
StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
} catch (IOException e) {
throw new RuntimeException(
"IOException encountered during compilation");
}
Boolean result = ct.call();
if (result == Boolean.FALSE) {
throw new RuntimeException(
"Compilation failure in " + type.getName() + " unit");
}
if (this.flags.contains(Flags.USECACHE)) {
File existing = cache.putIfAbsent(type.getName(), destDir);
if (existing != null) {
deleteDir(destDir);
return existing;
}
} else {
this.tempDirs.add(destDir);
}
return destDir;
}
private static void deleteDir(File dir) {
for (File f : dir.listFiles()) {
f.delete();
};
dir.delete();
}
public void cleanup() {
if (!this.flags.contains(Flags.USECACHE)) {
for (File d : tempDirs) {
deleteDir(d);
};
tempDirs = new ArrayList<>();
}
}
// Removes all of the elements in the cache and deletes the associated
// output directories. This may not actually empty the cache if there
// are concurrent users of it.
public static void purgeCache() {
for (Map.Entry<String,File> entry : cache.entrySet()) {
cache.remove(entry.getKey());
deleteDir(entry.getValue());
}
}
}

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package org.openjdk.tests.separate;
import java.util.HashMap;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
class DirectedClassLoader extends ClassLoader {
private HashMap<String,File> loadLocations;
private File defaultLocation;
private ClassFilePreprocessor[] preprocessors;
public DirectedClassLoader(
HashMap<String,File> locations, File fallback,
ClassFilePreprocessor ... preprocessors) {
loadLocations = new HashMap<>(locations);
defaultLocation = fallback;
this.preprocessors = preprocessors;
}
public DirectedClassLoader(
File fallback, ClassFilePreprocessor ... preprocessors) {
loadLocations = new HashMap<>();
defaultLocation = fallback;
this.preprocessors = preprocessors;
}
public DirectedClassLoader(ClassFilePreprocessor ... preprocessors) {
this((File)null, preprocessors);
}
public void setDefaultLocation(File dir) { this.defaultLocation = dir; }
public void setLocationFor(String name, File dir) {
loadLocations.put(name, dir);
}
@Override
protected Class<?> findClass(String name) {
String path = name.replace(".", File.separator) + ".class";
File location = loadLocations.get(name);
if (location == null || !(new File(location, path)).exists()) {
File def = new File(defaultLocation, path);
if (def.exists()) {
return defineFrom(name, new File(location, path));
}
} else {
return defineFrom(name, new File(location, path));
}
return null;
}
private Class<?> defineFrom(String name, File file) {
FileInputStream fis = null;
try {
try {
fis = new FileInputStream(file);
byte[] bytes = new byte[fis.available()];
int read = fis.read(bytes);
if (read != bytes.length) {
return null;
}
if (preprocessors != null) {
for (ClassFilePreprocessor cfp : preprocessors) {
bytes = cfp.preprocess(name, bytes);
}
}
return defineClass(name, bytes, 0, bytes.length);
} finally {
fis.close();
}
} catch (IOException e) {}
return null;
}
}

View file

@ -0,0 +1,582 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package org.openjdk.tests.separate;
import java.util.*;
import java.io.StringWriter;
import java.io.PrintWriter;
public class SourceModel {
public static final String stdMethodName = "m";
public static interface SourceProcessor {
// Called with a generated source file
void process(String name, String content);
}
public static abstract class Element {
protected abstract void generate(PrintWriter pw);
public String toString() {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
generate(pw);
return sw.toString();
}
};
public static class AccessFlag extends Element {
private String flag;
public AccessFlag(String name) { flag = name; }
protected void generate(PrintWriter pw) {
pw.print(flag);
}
public String toString() { return flag; }
public static final AccessFlag PUBLIC = new AccessFlag("public");
public static final AccessFlag PRIVATE = new AccessFlag("private");
public static final AccessFlag PROTECTED = new AccessFlag("protected");
public static final AccessFlag STATIC = new AccessFlag("static");
public static final AccessFlag FINAL = new AccessFlag("final");
public static final AccessFlag SYNCHRONIZED = new AccessFlag("synchronized");
public static final AccessFlag VOLATILE = new AccessFlag("volatile");
public static final AccessFlag NATIVE = new AccessFlag("native");
public static final AccessFlag ABSTRACT = new AccessFlag("abstract");
public static final AccessFlag STRICTFP = new AccessFlag("strictfp");
public static final AccessFlag DEFAULT = new AccessFlag("default");
}
public static class TypeParameter extends Element {
private String parameter;
public TypeParameter(String str) {
this.parameter = str;
}
protected void generate(PrintWriter pw) {
pw.print(parameter);
}
}
public static class TypeArgument extends Element {
private String argument;
public TypeArgument(String str) {
this.argument = str;
}
protected void generate(PrintWriter pw) {
pw.print(argument);
}
}
public static class MethodParameter extends Element {
private String type;
private String name;
public MethodParameter(String type, String name) {
this.type = type;
this.name = name;
}
protected void generate(PrintWriter pw) {
pw.printf("%s %s", this.type, this.name);
}
public String toString() { return type + " " + name; }
}
public static abstract class Type extends Element {
private String name;
private List<AccessFlag> accessFlags;
private List<TypeParameter> parameters;
private List<Extends> supertypes;
private List<Method> methods;
// methods from superclasses that are required for compilation
// (and thus will be present in stubs)
private Set<Method> methodDependencies;
private List<Type> typeDependencies;
protected Type(String name,
List<AccessFlag> flags, List<TypeParameter> params,
List<Extends> ifaces, List<Method> methods) {
this.name = name;
this.accessFlags = flags == null ? new ArrayList<>() : flags;
this.parameters = params == null ? new ArrayList<>() : params;
this.supertypes = ifaces == null ? new ArrayList<>() : ifaces;
this.methods = methods == null ? new ArrayList<>() : methods;
this.methodDependencies = new HashSet<>();
this.typeDependencies = new ArrayList<>();
}
public String getName() { return this.name; }
public List<AccessFlag> getAccessFlags() { return this.accessFlags; }
public List<TypeParameter> getParameters() { return this.parameters; }
public List<Extends> getSupertypes() { return this.supertypes; }
public List<Method> getMethods() { return this.methods; }
public Set<Method> methodDependencies() {
return this.methodDependencies;
}
public Class getSuperclass() { return null; }
protected abstract void setSuperClass(Extends supertype);
public void addSuperType(Extends sup) {
assert sup.getType() instanceof Interface : "Must be an interface";
this.supertypes.add(sup);
}
public void addSuperType(Interface iface) {
this.supertypes.add(new Extends(iface));
}
public void addMethod(Method m) {
this.methods.add(m);
}
public void addAccessFlag(AccessFlag f) {
this.accessFlags.add(f);
}
// Convenience method for creation. Parameters are interpreted
// according to their type. Class (or Extends with a Class type) is
// considered a superclass (only one allowed). TypeParameters are
// generic parameter names. Interface (or Extends with an Interface
// type) is an implemented supertype. Methods are methods (duh!).
protected void addComponent(Element p) {
if (p instanceof Class) {
setSuperClass(new Extends((Class)p));
} else if (p instanceof Extends) {
Extends ext = (Extends)p;
if (ext.supertype instanceof Class) {
setSuperClass(ext);
} else if (ext.supertype instanceof Interface) {
addSuperType(ext);
} else {
assert false : "What is this thing?";
}
} else if (p instanceof Interface) {
addSuperType((Interface)p);
} else if (p instanceof TypeParameter) {
this.parameters.add((TypeParameter)p);
} else if (p instanceof Method) {
addMethod((Method)p);
} else if (p instanceof AccessFlag) {
addAccessFlag((AccessFlag)p);
} else {
assert false : "What is this thing?";
}
}
// Find and return the first method that has name 'name'
public Method findMethod(String name) {
for (Method m : methods) {
if (m.name.equals(name)) {
return m;
}
}
return null;
}
public void addCompilationDependency(Type t) {
typeDependencies.add(t);
}
public void addCompilationDependency(Method m) {
methodDependencies.add(m);
}
// Convenience method for creating an Extends object using this
// class and specified type arguments.
public Extends with(String ... args) {
return new Extends(this, args);
}
public abstract void generate(SourceProcessor sp);
public abstract void generateAsDependency(
SourceProcessor sp, Set<Method> neededMethods);
protected void generateName(PrintWriter pw) {
pw.print(this.name);
toJoinedString(this.parameters, ",", "<", ">", "");
pw.print(toJoinedString(this.parameters, ",", "<", ">", ""));
pw.print(" ");
}
protected void generateBody(PrintWriter pw, String superSpec) {
pw.print(toJoinedString(this.supertypes, ",", superSpec + " ", " ", ""));
pw.println("{ ");
pw.print(toJoinedString(this.methods, "\n ", "\n ", "\n", ""));
pw.println("}");
}
protected void generateAccessFlags(PrintWriter pw) {
pw.print(toJoinedString(this.accessFlags, " ", "", " "));
}
protected void generateBodyAsDependency(
PrintWriter pw, Set<Method> neededMethods) {
pw.println(" {");
for (Method m : this.methods) {
if (neededMethods.contains(m)) {
pw.print(" ");
m.generate(pw);
pw.println();
}
}
pw.println("}");
}
public Collection<Type> typeDependencies() {
HashMap<String,Type> dependencies = new HashMap<>();
Type superclass = getSuperclass();
if (superclass != null) {
dependencies.put(superclass.getName(), superclass);
}
for (Extends e : getSupertypes())
dependencies.put(e.getType().getName(), e.getType());
// Do these last so that they override
for (Type t : this.typeDependencies)
dependencies.put(t.getName(), t);
return dependencies.values();
}
}
public static class Class extends Type {
private Extends superClass;
public Class(String name, List<AccessFlag> flags,
List<TypeParameter> params, Extends sprClass,
List<Extends> interfaces, List<Method> methods) {
super(name, flags, params, interfaces, methods);
this.superClass = sprClass;
addAccessFlag(AccessFlag.PUBLIC); // should remove this
}
public Class(String name, Element ... components) {
super(name, null, null, null, null);
this.superClass = null;
for (Element p : components) {
addComponent(p);
}
addAccessFlag(AccessFlag.PUBLIC); // should remove this
}
public boolean isAbstract() {
for (AccessFlag flag : getAccessFlags()) {
if (flag == AccessFlag.ABSTRACT) {
return true;
}
}
return false;
}
@Override
public void setSuperClass(Extends ext) {
assert this.superClass == null : "Multiple superclasses defined";
assert ext.getType() instanceof Class : "Must be a class";
this.superClass = ext;
}
public void setSuperClass(Class c) {
setSuperClass(new Extends(c));
}
@Override
public Class getSuperclass() {
return superClass == null ? null : (Class)superClass.supertype;
}
public void generate(SourceProcessor processor) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
generate(pw);
processor.process(getName(), sw.toString());
}
public void generate(PrintWriter pw) {
generateAccessFlags(pw);
pw.print("class ");
generateName(pw);
if (superClass != null) {
pw.print("extends ");
superClass.generate(pw);
pw.print(" ");
}
generateBody(pw, "implements");
}
public void generateAsDependency(
SourceProcessor processor, Set<Method> neededMethods) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
generateAccessFlags(pw);
pw.print("class ");
generateName(pw);
pw.print(" ");
generateBodyAsDependency(pw, neededMethods);
processor.process(getName(), sw.toString());
}
}
public static class Interface extends Type {
public Interface(String name,
List<AccessFlag> flags, List<TypeParameter> params,
List<Extends> interfaces, List<Method> methods) {
super(name, flags, params, interfaces, methods);
}
public Interface(String name, Element ... components) {
super(name, null, null, null, null);
for (Element c : components) {
addComponent(c);
}
}
protected void setSuperClass(Extends ext) {
assert false : "Interfaces cannot have Class supertypes";
}
public void generate(SourceProcessor processor) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
generate(pw);
processor.process(getName(), sw.toString());
}
public void generate(PrintWriter pw) {
generateAccessFlags(pw);
pw.print("interface ");
generateName(pw);
pw.print(" ");
generateBody(pw, "extends");
}
public void generateAsDependency(
SourceProcessor processor, Set<Method> neededMethods) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
generateAccessFlags(pw);
pw.print("interface ");
generateName(pw);
pw.print(" ");
generateBodyAsDependency(pw, neededMethods);
processor.process(getName(), sw.toString());
}
}
/**
* Represents a type extension that might contain type arguments
*/
public static class Extends extends Element {
private final Type supertype;
private final List<TypeArgument> arguments;
public Type getType() { return supertype; }
public List<TypeArgument> getArguments() {
return arguments;
}
public Extends(Type supertype, String ... args) {
assert supertype != null : "Null supertype";
this.supertype = supertype;
this.arguments = new ArrayList<>();
for (String arg : args) {
this.arguments.add(new TypeArgument(arg));
}
}
public void generate(PrintWriter pw) {
pw.print(supertype.getName());
pw.print(toJoinedString(getArguments(), ",", "<", ">", ""));
}
}
public static abstract class Method extends Element {
private String name;
private String returnType;
private List<AccessFlag> accessFlags;
private List<MethodParameter> parameters;
private boolean emitSuppressWarnings;
protected Method(String ret, String name, Element ... params) {
this.name = name;
this.returnType = ret;
this.accessFlags = new ArrayList<>();
this.parameters = new ArrayList<>();
this.emitSuppressWarnings = false;
for (Element e : params) {
if (e instanceof MethodParameter) {
this.parameters.add((MethodParameter) e);
} else if (e instanceof AccessFlag) {
this.accessFlags.add((AccessFlag) e);
}
}
assert accessFlags.size() + parameters.size() == params.length :
"Non method parameters or access flags in constructor";
}
public String getName() { return this.name; }
public String getReturnType() { return this.returnType; }
public List<MethodParameter> getParameters() {
return this.parameters;
}
public List<AccessFlag> getAccessFlags() {
return this.accessFlags;
}
public Element[] getElements() {
ArrayList<Element> elements = new ArrayList<>();
elements.addAll(getParameters());
elements.addAll(getAccessFlags());
return elements.toArray(new Element[0]);
}
public void suppressWarnings() { this.emitSuppressWarnings = true; }
public void generateWarningSuppression(PrintWriter pw) {
if (this.emitSuppressWarnings) {
pw.printf("@SuppressWarnings(\"unchecked\")\n ");
}
}
protected void generateDecl(PrintWriter pw) {
generateWarningSuppression(pw);
pw.print(toJoinedString(this.accessFlags, " ", "", " "));
pw.printf("%s %s(", returnType, name);
pw.print(toJoinedString(parameters, ","));
pw.print(")");
}
}
public static class AbstractMethod extends Method {
public AbstractMethod(
String ret, String name, Element ... params) {
super(ret, name, params);
this.getAccessFlags().add(AccessFlag.ABSTRACT);
}
public void generate(PrintWriter pw) {
generateDecl(pw);
pw.print(";");
}
public static AbstractMethod std() {
return new AbstractMethod(
"int", SourceModel.stdMethodName, AccessFlag.PUBLIC);
}
}
public static class ConcreteMethod extends Method {
protected String body;
public ConcreteMethod(String ret, String name,
String body, Element ... params) {
super(ret, name, params);
this.body = body;
}
public void generate(PrintWriter pw) {
generateDecl(pw);
pw.printf(" { %s }", this.body);
}
public static ConcreteMethod std(String value) {
return new ConcreteMethod(
"int", SourceModel.stdMethodName, "return " + value + ";",
AccessFlag.PUBLIC);
}
}
// When the default method flag gets moved into the traditional
// access flags location, we can remove this class completely and
// use a ConcreteMethod with an AccessFlag("default") in the constructor
public static class DefaultMethod extends Method {
protected String body;
public DefaultMethod(String ret, String name, String body,
Element ... params) {
super(ret, name, params);
this.body = body;
this.getAccessFlags().add(AccessFlag.DEFAULT);
}
public void generate(PrintWriter pw) {
generateDecl(pw);
pw.printf(" { %s }", this.body);
}
public static DefaultMethod std(String value) {
return new DefaultMethod(
"int", SourceModel.stdMethodName, "return " + value + ";");
}
}
private static <T> String toJoinedString(List<T> list, String... p) {
StringBuilder sb = new StringBuilder();
String sep = "";
String init = "";
String end = "";
String empty = null;
switch (p.length) {
case 4:
empty = p[3];
/*fall-through*/
case 3:
end = p[2];
/*fall-through*/
case 2:
init = p[1];
/*fall-through*/
case 1:
sep = p[0];
break;
}
if (empty != null && list.isEmpty()) {
return empty;
} else {
sb.append(init);
for (T x : list) {
if (sb.length() != init.length()) {
sb.append(sep);
}
sb.append(x.toString());
}
sb.append(end);
return sb.toString();
}
}
}

View file

@ -0,0 +1,354 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package org.openjdk.tests.separate;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import static org.openjdk.tests.separate.SourceModel.Class;
import static org.openjdk.tests.separate.SourceModel.*;
import static org.testng.Assert.*;
public class TestHarness {
/**
* Creates a per-thread persistent compiler object to allow as much
* sharing as possible, but still allows for parallel execution of tests.
*/
protected ThreadLocal<Compiler> compilerLocal = new ThreadLocal<Compiler>(){
protected synchronized Compiler initialValue() {
return new Compiler();
}
};
protected ThreadLocal<Boolean> verboseLocal = new ThreadLocal<Boolean>() {
protected synchronized Boolean initialValue() {
return Boolean.FALSE;
}
};
protected boolean verbose;
protected boolean canUseCompilerCache;
public static final String stdMethodName = SourceModel.stdMethodName;
private TestHarness() {
}
protected TestHarness(boolean verbose, boolean canUseCompilerCache) {
this.verbose = verbose;
this.canUseCompilerCache = canUseCompilerCache;
}
public void setTestVerbose() {
verboseLocal.set(Boolean.TRUE);
}
@AfterMethod
public void reset() {
if (!this.verbose) {
verboseLocal.set(Boolean.FALSE);
}
}
public Compiler.Flags[] compilerFlags() {
HashSet<Compiler.Flags> flags = new HashSet<>();
if (verboseLocal.get() == Boolean.TRUE) {
flags.add(Compiler.Flags.VERBOSE);
}
if (this.canUseCompilerCache) {
flags.add(Compiler.Flags.USECACHE);
}
return flags.toArray(new Compiler.Flags[0]);
}
@AfterMethod
public void printError(ITestResult result) {
if (result.getStatus() == ITestResult.FAILURE) {
String clsName = result.getTestClass().getName();
clsName = clsName.substring(clsName.lastIndexOf(".") + 1);
System.out.println("Test " + clsName + "." +
result.getName() + " FAILED");
}
}
private static final ConcreteMethod stdCM = ConcreteMethod.std("-1");
private static final AbstractMethod stdAM =
new AbstractMethod("int", stdMethodName);
/**
* Returns a class which has a static method with the same name as
* 'method', whose body creates an new instance of 'specimen' and invokes
* 'method' upon it via an invokevirtual instruction with 'args' as
* function call parameters.
*
* 'returns' is a dummy return value that need only match 'methods'
* return type (it is only used in the dummy class when compiling IV).
*/
private Class invokeVirtualHarness(
Class specimen, ConcreteMethod method,
String returns, String ... args) {
Method cm = new ConcreteMethod(
method.getReturnType(), method.getName(),
"return " + returns + ";", method.getElements());
Class stub = new Class(specimen.getName(), cm);
String params = toJoinedString(args, ", ");
ConcreteMethod sm = new ConcreteMethod(
method.getReturnType(), method.getName(),
String.format("return (new %s()).%s(%s);",
specimen.getName(), method.getName(), params),
new AccessFlag("public"), new AccessFlag("static"));
Class iv = new Class("IV_" + specimen.getName(), sm);
iv.addCompilationDependency(stub);
iv.addCompilationDependency(cm);
return iv;
}
/**
* Returns a class which has a static method with the same name as
* 'method', whose body creates an new instance of 'specimen', casts it
* to 'iface' (including the type parameters) and invokes
* 'method' upon it via an invokeinterface instruction with 'args' as
* function call parameters.
*/
private Class invokeInterfaceHarness(Class specimen, Extends iface,
AbstractMethod method, String ... args) {
Interface istub = new Interface(
iface.getType().getName(), iface.getType().getAccessFlags(),
iface.getType().getParameters(),
null, Arrays.asList((Method)method));
Class cstub = new Class(specimen.getName());
String params = toJoinedString(args, ", ");
ConcreteMethod sm = new ConcreteMethod(
"int", SourceModel.stdMethodName,
String.format("return ((%s)(new %s())).%s(%s);", iface.toString(),
specimen.getName(), method.getName(), params),
new AccessFlag("public"), new AccessFlag("static"));
sm.suppressWarnings();
Class ii = new Class("II_" + specimen.getName() + "_" +
iface.getType().getName(), sm);
ii.addCompilationDependency(istub);
ii.addCompilationDependency(cstub);
ii.addCompilationDependency(method);
return ii;
}
/**
* Uses 'loader' to load class 'clzz', and calls the static method
* 'method'. If the return value does not equal 'value' (or if an
* exception is thrown), then a test failure is indicated.
*
* If 'value' is null, then no equality check is performed -- the assertion
* fails only if an exception is thrown.
*/
protected void assertStaticCallEquals(
ClassLoader loader, Class clzz, String method, Object value) {
java.lang.Class<?> cls = null;
try {
cls = java.lang.Class.forName(clzz.getName(), true, loader);
} catch (ClassNotFoundException e) {}
assertNotNull(cls);
java.lang.reflect.Method m = null;
try {
m = cls.getMethod(method);
} catch (NoSuchMethodException e) {}
assertNotNull(m);
try {
Object res = m.invoke(null);
assertNotNull(res);
if (value != null) {
assertEquals(res, value);
}
} catch (InvocationTargetException | IllegalAccessException e) {
fail("Unexpected exception thrown: " + e.getCause());
}
}
/**
* Creates a class which calls target::method(args) via invokevirtual,
* compiles and loads both the new class and 'target', and then invokes
* the method. If the returned value does not match 'value' then a
* test failure is indicated.
*/
public void assertInvokeVirtualEquals(
Object value, Class target, ConcreteMethod method,
String returns, String ... args) {
Compiler compiler = compilerLocal.get();
compiler.setFlags(compilerFlags());
Class iv = invokeVirtualHarness(target, method, returns, args);
ClassLoader loader = compiler.compile(iv, target);
assertStaticCallEquals(loader, iv, method.getName(), value);
compiler.cleanup();
}
/**
* Convenience method for above, which assumes stdMethodName,
* a return type of 'int', and no arguments.
*/
public void assertInvokeVirtualEquals(int value, Class target) {
assertInvokeVirtualEquals(
new Integer(value), target, stdCM, "-1");
}
/**
* Creates a class which calls target::method(args) via invokeinterface
* through 'iface', compiles and loads both it and 'target', and
* then invokes the method. If the returned value does not match
* 'value' then a test failure is indicated.
*/
public void assertInvokeInterfaceEquals(Object value, Class target,
Extends iface, AbstractMethod method, String ... args) {
Compiler compiler = compilerLocal.get();
compiler.setFlags(compilerFlags());
Class ii = invokeInterfaceHarness(target, iface, method, args);
ClassLoader loader = compiler.compile(ii, target);
assertStaticCallEquals(loader, ii, method.getName(), value);
compiler.cleanup();
}
/**
* Convenience method for above, which assumes stdMethodName,
* a return type of 'int', and no arguments.
*/
public void assertInvokeInterfaceEquals(
int value, Class target, Interface iface) {
Compiler compiler = compilerLocal.get();
compiler.setFlags(compilerFlags());
assertInvokeInterfaceEquals(
new Integer(value), target, new Extends(iface), stdAM);
compiler.cleanup();
}
/**
* Creates a class which calls target::method(args) via invokevirtual,
* compiles and loads both the new class and 'target', and then invokes
* the method. If an exception of type 'exceptionType' is not thrown,
* then a test failure is indicated.
*/
public void assertThrows(java.lang.Class<?> exceptionType, Class target,
ConcreteMethod method, String returns, String ... args) {
Compiler compiler = compilerLocal.get();
compiler.setFlags(compilerFlags());
Class iv = invokeVirtualHarness(target, method, returns, args);
ClassLoader loader = compiler.compile(iv, target);
java.lang.Class<?> cls = null;
try {
cls = java.lang.Class.forName(iv.getName(), true, loader);
} catch (ClassNotFoundException e) {}
assertNotNull(cls);
java.lang.reflect.Method m = null;
try {
m = cls.getMethod(method.getName());
} catch (NoSuchMethodException e) {}
assertNotNull(m);
try {
m.invoke(null);
fail("Exception should have been thrown");
} catch (InvocationTargetException | IllegalAccessException e) {
if (verboseLocal.get() == Boolean.TRUE) {
System.out.println(e.getCause());
}
assertEquals(e.getCause().getClass(), exceptionType);
}
compiler.cleanup();
}
/**
* Convenience method for above, which assumes stdMethodName,
* a return type of 'int', and no arguments.
*/
public void assertThrows(java.lang.Class<?> exceptionType, Class target) {
assertThrows(exceptionType, target, stdCM, "-1");
}
private static <T> String toJoinedString(T[] a, String... p) {
return toJoinedString(Arrays.asList(a), p);
}
private static <T> String toJoinedString(List<T> list, String... p) {
StringBuilder sb = new StringBuilder();
String sep = "";
String init = "";
String end = "";
String empty = null;
switch (p.length) {
case 4:
empty = p[3];
/*fall-through*/
case 3:
end = p[2];
/*fall-through*/
case 2:
init = p[1];
/*fall-through*/
case 1:
sep = p[0];
break;
}
if (empty != null && list.isEmpty()) {
return empty;
} else {
sb.append(init);
for (T x : list) {
if (sb.length() != init.length()) {
sb.append(sep);
}
sb.append(x.toString());
}
sb.append(end);
return sb.toString();
}
}
}

View file

@ -23,7 +23,7 @@
* questions.
*/
package shapegen;
package org.openjdk.tests.shapegen;
import java.util.ArrayList;
import java.util.HashSet;
@ -52,6 +52,8 @@ public class ClassCase {
this.isInterface = isInterface;
this.prefix = prefix;
}
public String getPrefix() { return prefix; }
}
public final Kind kind;
@ -67,7 +69,7 @@ public class ClassCase {
private ClassCase _mres;
private ClassCase _mdefend;
private Set<RuleGroup> executed = new HashSet<RuleGroup>() {};
private Set<RuleGroup> executed = new HashSet<RuleGroup>();
public ClassCase(Kind kind, ClassCase superclass, List<ClassCase> interfaces) {
this.kind = kind;

View file

@ -23,14 +23,16 @@
* questions.
*/
package shapegen;
package org.openjdk.tests.shapegen;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static shapegen.ClassCase.Kind.*;
import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
/**
*
@ -140,4 +142,68 @@ public class Hierarchy {
return root.getName();
}
private static String classNames[] = {
"C", "D", "E", "F", "G", "H", "S", "T", "U", "V"
};
private static String interfaceNames[] = {
"I", "J", "K", "L", "M", "N", "O", "P", "Q", "R"
};
private static int CLASS_INDEX = 0;
private static int INTERFACE_INDEX = 1;
private static int NUM_INDICIES = 2;
public List<String> getDescription() {
Map<ClassCase,String> nameMap = new HashMap<>();
assignNames(root, new int[NUM_INDICIES], nameMap);
ArrayList<String> res = new ArrayList<>();
if (root.getSupertypes().size() == 0) {
res.add(nameMap.get(root) + root.kind.getPrefix() + "()");
} else {
genCaseDescription(root, res, new HashSet<ClassCase>(), nameMap);
}
return res;
}
private static void assignNames(
ClassCase cc, int indices[], Map<ClassCase,String> names) {
String name = names.get(cc);
if (name == null) {
if (cc.isInterface()) {
names.put(cc, interfaceNames[indices[INTERFACE_INDEX]++]);
} else {
names.put(cc, classNames[indices[CLASS_INDEX]++]);
}
for (int i = 0; i < cc.getSupertypes().size(); ++i) {
assignNames(cc.getSupertypes().get(i), indices, names);
}
}
}
private static void genCaseDescription(
ClassCase cc, List<String> res, Set<ClassCase> alreadyDone,
Map<ClassCase,String> nameMap) {
if (!alreadyDone.contains(cc)) {
if (cc.getSupertypes().size() > 0) {
StringBuilder sb = new StringBuilder();
sb.append(nameMap.get(cc));
sb.append(cc.kind.getPrefix());
sb.append("(");
for (int i = 0; i < cc.getSupertypes().size(); ++i) {
ClassCase supertype = cc.getSupertypes().get(i);
if (i != 0) {
sb.append(",");
}
genCaseDescription(supertype, res, alreadyDone, nameMap);
sb.append(nameMap.get(supertype));
sb.append(supertype.kind.getPrefix());
}
sb.append(")");
res.add(sb.toString());
}
}
alreadyDone.add(cc);
}
}

View file

@ -23,9 +23,9 @@
* questions.
*/
package shapegen;
package org.openjdk.tests.shapegen;
import shapegen.ClassCase.Kind;
import org.openjdk.tests.shapegen.ClassCase.Kind;
import java.util.Collection;
import java.util.Set;
@ -34,7 +34,7 @@ import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import static shapegen.ClassCase.Kind.*;
import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
import static java.lang.Math.pow;
@ -44,10 +44,10 @@ import static java.lang.Math.pow;
*/
public final class HierarchyGenerator {
private static int okcnt = 0;
private static int errcnt = 0;
private static Set<Hierarchy> uniqueOK = new HashSet<>();
private static Set<Hierarchy> uniqueErr = new HashSet<>();
private int okcnt = 0;
private int errcnt = 0;
private Set<Hierarchy> uniqueOK = new HashSet<>();
private Set<Hierarchy> uniqueErr = new HashSet<>();
/**
* @param args the command line arguments
@ -71,7 +71,7 @@ public final class HierarchyGenerator {
}
private void organize(String tname, List<Hierarchy> totest) {
System.out.printf("\nTesting %s....\n", tname);
System.out.printf("\nGenerating %s....\n", tname);
int nodefault = 0;
List<Hierarchy> ok = new ArrayList<>();
List<Hierarchy> err = new ArrayList<>();
@ -152,12 +152,14 @@ public final class HierarchyGenerator {
return totest;
}
public static final List<ClassCase> EMPTY_LIST = new ArrayList<>();
private List<ClassCase> iList(Kind kind) {
if (kind == null) {
return Collections.EMPTY_LIST;
return EMPTY_LIST;
} else {
List<ClassCase> itfs = new ArrayList<>();
itfs.add(new ClassCase(kind, null, Collections.EMPTY_LIST));
itfs.add(new ClassCase(kind, null, EMPTY_LIST));
return itfs;
}
}

View file

@ -23,7 +23,7 @@
* questions.
*/
package shapegen;
package org.openjdk.tests.shapegen;
/**
*

View file

@ -0,0 +1,206 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package org.openjdk.tests.shapegen;
import java.util.HashSet;
import java.util.Set;
import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
/**
*
* @author Robert Field
*/
public class RuleGroup {
final String name;
private final Rule[] rules;
public RuleGroup(String name, Rule[] rules) {
this.name = name;
this.rules = rules;
}
public boolean exec(ClassCase cc) {
boolean found = false;
for (Rule rule : rules) {
if (rule.guard(cc)) {
if (found) {
throw new RuntimeException("Bad rules -- multiple matches " + toString() + " for " + cc);
} else {
rule.eval(cc);
found = true;
}
}
}
return found;
}
@Override
public String toString() {
return name;
}
public static RuleGroup PROVENENCE = new RuleGroup("Provenence", new Rule[] {
new Rule("P-CDeclare") {
boolean guard(ClassCase cc) {
return cc.isa(CCONCRETE, CABSTRACT);
}
void eval(ClassCase cc) {
cc.set_mprov(cc);
cc.set_HasClassMethod(true);
}
},
new Rule("P-IDeclare") {
boolean guard(ClassCase cc) {
return cc.isa(IDEFAULT, IPRESENT);
}
void eval(ClassCase cc) {
cc.set_mprov(cc);
}
},
new Rule("P-IntfInh") {
boolean guard(ClassCase cc) {
return cc.isa(IVAC, CNONE) && !(cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
}
void eval(ClassCase cc) {
Set<ClassCase> _S = new HashSet<>();
for (ClassCase t : cc.getSupertypes()) {
_S.addAll(t.get_mprov());
}
Set<ClassCase> tops = new HashSet<>();
for (ClassCase _W : _S) {
for (ClassCase _V : _S) {
if (_V.equals(_W) || !(_V.isSubtypeOf(_W))) {
tops.add(_W);
}
}
}
cc.set_mprov(tops);
}
},
new Rule("P-ClassInh") {
boolean guard(ClassCase cc) {
return cc.isa(CNONE) && (cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
}
void eval(ClassCase cc) {
cc.set_mprov(cc.getSuperclass());
cc.set_HasClassMethod(true);
}
},
});
public static RuleGroup MARKER = new RuleGroup("Marker", new Rule[] {
new Rule("M-Default") {
boolean guard(ClassCase cc) {
return cc.isa(IDEFAULT);
}
void eval(ClassCase cc) {
cc.set_HasDefault(true);
}
},
new Rule("M-Conc") {
boolean guard(ClassCase cc) {
return cc.isa(CCONCRETE);
}
void eval(ClassCase cc) {
cc.set_IsConcrete(true);
}
},
});
public static RuleGroup RESOLUTION = new RuleGroup("Resolution", new Rule[] {
new Rule("R-Resolve") {
boolean guard(ClassCase cc) {
if (!(cc.isClass() && cc.get_mprov().size() == 1)) {
return false;
}
ClassCase _V = cc.get_mprov().iterator().next();
return _V.get_IsConcrete() || _V.get_HasDefault();
}
void eval(ClassCase cc) {
ClassCase _V = cc.get_mprov().iterator().next();
cc.set_mres(_V);
}
},
});
public static RuleGroup DEFENDER = new RuleGroup("Defender", new Rule[] {
new Rule("D-Defend") {
boolean guard(ClassCase cc) {
ClassCase mresSuper = cc.hasSuperclass() ? cc.getSuperclass().get_mres() : null;
boolean eq = cc.get_mres() == null ? mresSuper == null : cc.get_mres().equals(mresSuper);
return cc.isa(CNONE) && !eq;
}
void eval(ClassCase cc) {
cc.set_mdefend(cc.get_mres());
}
},
});
public static RuleGroup CHECKING = new RuleGroup("Checking", new Rule[] {
new Rule("C-Check") {
boolean guard(ClassCase cc) {
for (ClassCase t : cc.getSupertypes()) {
if (! t.get_OK()) {
return false;
}
}
int defenderCount = 0;
int provCount = 0;
for (ClassCase prov : cc.get_mprov()) {
if (prov.get_HasDefault()) {
defenderCount++;
}
provCount++;
}
return provCount <= 1 || defenderCount == 0;
}
void eval(ClassCase cc) {
cc.set_OK(true);
}
},
});
}

View file

@ -23,15 +23,15 @@
* questions.
*/
package shapegen;
package org.openjdk.tests.shapegen;
import shapegen.ClassCase.Kind;
import org.openjdk.tests.shapegen.ClassCase.Kind;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static shapegen.ClassCase.Kind.*;
import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
/**
* Type Template Node

View file

@ -23,7 +23,7 @@
* questions.
*/
package shapegen;
package org.openjdk.tests.shapegen;
import java.util.ArrayList;
import java.util.HashMap;

View file

@ -23,7 +23,7 @@
* questions.
*/
package shapegen;
package org.openjdk.tests.shapegen;
import java.util.ArrayList;
import java.util.HashSet;

View file

@ -0,0 +1,826 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package org.openjdk.tests.vm;
import java.lang.reflect.*;
import java.util.*;
import java.io.File;
import java.io.IOException;
import org.testng.annotations.Test;
import org.openjdk.tests.separate.*;
import org.openjdk.tests.separate.Compiler;
import static org.testng.Assert.*;
import static org.openjdk.tests.separate.SourceModel.*;
import static org.openjdk.tests.separate.SourceModel.Class;
@Test(groups = "vm")
public class DefaultMethodsTest extends TestHarness {
public DefaultMethodsTest() {
super(false, false);
}
/**
* class C { public int m() { return 22; } }
*
* TEST: C c = new C(); c.m() == 22
*/
public void testHarnessInvokeVirtual() {
Class C = new Class("C", ConcreteMethod.std("22"));
assertInvokeVirtualEquals(22, C);
}
/**
* interface I { int m(); }
* class C implements I { public int m() { return 33; } }
*
* TEST: I i = new C(); i.m() == 33;
*/
public void testHarnessInvokeInterface() {
Interface I = new Interface("I", AbstractMethod.std());
Class C = new Class("C", I, ConcreteMethod.std("33"));
assertInvokeInterfaceEquals(33, C, I);
}
/**
* class C {}
*
* TEST: C c = new C(); c.m() throws NoSuchMethod
*/
public void testHarnessThrows() {
Class C = new Class("C");
assertThrows(NoSuchMethodError.class, C);
}
/**
* interface I { int m() default { return 44; } }
* class C implements I {}
*
* TEST: C c = new C(); c.m() == 44;
* TEST: I i = new C(); i.m() == 44;
*/
public void testBasicDefault() {
Interface I = new Interface("I", DefaultMethod.std("44"));
Class C = new Class("C", I);
assertInvokeVirtualEquals(44, C);
assertInvokeInterfaceEquals(44, C, I);
}
/**
* interface I { default int m() { return 44; } }
* interface J extends I {}
* interface K extends J {}
* class C implements K {}
*
* TEST: C c = new C(); c.m() == 44;
* TEST: I i = new C(); i.m() == 44;
*/
public void testFarDefault() {
Interface I = new Interface("I", DefaultMethod.std("44"));
Interface J = new Interface("J", I);
Interface K = new Interface("K", J);
Class C = new Class("C", K);
assertInvokeVirtualEquals(44, C);
assertInvokeInterfaceEquals(44, C, K);
}
/**
* interface I { int m(); }
* interface J extends I { default int m() { return 44; } }
* interface K extends J {}
* class C implements K {}
*
* TEST: C c = new C(); c.m() == 44;
* TEST: K k = new C(); k.m() == 44;
*/
public void testOverrideAbstract() {
Interface I = new Interface("I", AbstractMethod.std());
Interface J = new Interface("J", I, DefaultMethod.std("44"));
Interface K = new Interface("K", J);
Class C = new Class("C", K);
assertInvokeVirtualEquals(44, C);
assertInvokeInterfaceEquals(44, C, K);
}
/**
* interface I { int m() default { return 44; } }
* class C implements I { public int m() { return 55; } }
*
* TEST: C c = new C(); c.m() == 55;
* TEST: I i = new C(); i.m() == 55;
*/
public void testExisting() {
Interface I = new Interface("I", DefaultMethod.std("44"));
Class C = new Class("C", I, ConcreteMethod.std("55"));
assertInvokeVirtualEquals(55, C);
assertInvokeInterfaceEquals(55, C, I);
}
/**
* interface I { default int m() { return 99; } }
* class B implements I {}
* class C extends B {}
*
* TEST: C c = new C(); c.m() == 99;
* TEST: I i = new C(); i.m() == 99;
*/
public void testInherited() {
Interface I = new Interface("I", DefaultMethod.std("99"));
Class B = new Class("B", I);
Class C = new Class("C", B);
assertInvokeVirtualEquals(99, C);
assertInvokeInterfaceEquals(99, C, I);
}
/**
* interface I { default int m() { return 99; } }
* class C { public int m() { return 11; } }
* class D extends C implements I {}
*
* TEST: D d = new D(); d.m() == 11;
* TEST: I i = new D(); i.m() == 11;
*/
public void testExistingInherited() {
Interface I = new Interface("I", DefaultMethod.std("99"));
Class C = new Class("C", ConcreteMethod.std("11"));
Class D = new Class("D", C, I);
assertInvokeVirtualEquals(11, D);
assertInvokeInterfaceEquals(11, D, I);
}
/**
* interface I { default int m() { return 44; } }
* class C implements I { public int m() { return 11; } }
* class D extends C { public int m() { return 22; } }
*
* TEST: D d = new D(); d.m() == 22;
* TEST: I i = new D(); i.m() == 22;
*/
void testExistingInheritedOverride() {
Interface I = new Interface("I", DefaultMethod.std("99"));
Class C = new Class("C", I, ConcreteMethod.std("11"));
Class D = new Class("D", C, ConcreteMethod.std("22"));
assertInvokeVirtualEquals(22, D);
assertInvokeInterfaceEquals(22, D, I);
}
/**
* interface I { default int m() { return 99; } }
* interface J { defaultint m() { return 88; } }
* class C implements I { public int m() { return 11; } }
* class D extends C { public int m() { return 22; } }
* class E extends D implements J {}
*
* TEST: E e = new E(); e.m() == 22;
* TEST: J j = new E(); j.m() == 22;
*/
public void testExistingInheritedPlusDefault() {
Interface I = new Interface("I", DefaultMethod.std("99"));
Interface J = new Interface("J", DefaultMethod.std("88"));
Class C = new Class("C", I, ConcreteMethod.std("11"));
Class D = new Class("D", C, ConcreteMethod.std("22"));
Class E = new Class("E", D, J);
assertInvokeVirtualEquals(22, E);
assertInvokeInterfaceEquals(22, E, J);
}
/**
* interface I { default int m() { return 99; } }
* class B implements I {}
* class C extends B { public int m() { return 77; } }
*
* TEST: C c = new C(); c.m() == 77;
* TEST: I i = new C(); i.m() == 77;
*/
public void testInheritedWithConcrete() {
Interface I = new Interface("I", DefaultMethod.std("99"));
Class B = new Class("B", I);
Class C = new Class("C", B, ConcreteMethod.std("77"));
assertInvokeVirtualEquals(77, C);
assertInvokeInterfaceEquals(77, C, I);
}
/**
* interface I { default int m() { return 99; } }
* class B implements I {}
* class C extends B implements I { public int m() { return 66; } }
*
* TEST: C c = new C(); c.m() == 66;
* TEST: I i = new C(); i.m() == 66;
*/
public void testInheritedWithConcreteAndImpl() {
Interface I = new Interface("I", DefaultMethod.std("99"));
Class B = new Class("B", I);
Class C = new Class("C", B, I, ConcreteMethod.std("66"));
assertInvokeVirtualEquals(66, C);
assertInvokeInterfaceEquals(66, C, I);
}
/**
* interface I { default int m() { return 99; } }
* interface J { default int m() { return 88; } }
* class C implements I, J {}
*
* TEST: C c = new C(); c.m() throws AME
*/
public void testConflict() {
// debugTest();
Interface I = new Interface("I", DefaultMethod.std("99"));
Interface J = new Interface("J", DefaultMethod.std("88"));
Class C = new Class("C", I, J);
assertThrows(AbstractMethodError.class, C);
}
/**
* interface I { int m(); }
* interface J { default int m() { return 88; } }
* class C implements I, J {}
*
* TEST: C c = new C(); c.m() throws AME
*/
public void testAmbiguousReabstract() {
Interface I = new Interface("I", AbstractMethod.std());
Interface J = new Interface("J", DefaultMethod.std("88"));
Class C = new Class("C", I, J);
assertThrows(AbstractMethodError.class, C);
}
/**
* interface I { default int m() { return 99; } }
* interface J extends I { }
* interface K extends I { }
* class C implements J, K {}
*
* TEST: C c = new C(); c.m() == 99
* TEST: J j = new C(); j.m() == 99
* TEST: K k = new C(); k.m() == 99
* TEST: I i = new C(); i.m() == 99
*/
public void testDiamond() {
Interface I = new Interface("I", DefaultMethod.std("99"));
Interface J = new Interface("J", I);
Interface K = new Interface("K", I);
Class C = new Class("C", J, K);
assertInvokeVirtualEquals(99, C);
assertInvokeInterfaceEquals(99, C, J);
assertInvokeInterfaceEquals(99, C, K);
assertInvokeInterfaceEquals(99, C, I);
}
/**
* interface I { default int m() { return 99; } }
* interface J extends I { }
* interface K extends I { }
* interface L extends I { }
* interface M extends I { }
* class C implements I, J, K, L, M {}
*
* TEST: C c = new C(); c.m() == 99
* TEST: J j = new C(); j.m() == 99
* TEST: K k = new C(); k.m() == 99
* TEST: I i = new C(); i.m() == 99
* TEST: L l = new C(); l.m() == 99
* TEST: M m = new C(); m.m() == 99
*/
public void testExpandedDiamond() {
Interface I = new Interface("I", DefaultMethod.std("99"));
Interface J = new Interface("J", I);
Interface K = new Interface("K", I);
Interface L = new Interface("L", I);
Interface M = new Interface("M", L);
Class C = new Class("C", I, J, K, L, M);
assertInvokeVirtualEquals(99, C);
assertInvokeInterfaceEquals(99, C, J);
assertInvokeInterfaceEquals(99, C, K);
assertInvokeInterfaceEquals(99, C, I);
assertInvokeInterfaceEquals(99, C, L);
assertInvokeInterfaceEquals(99, C, M);
}
/**
* interface I { int m() default { return 99; } }
* interface J extends I { int m(); }
* class C implements J {}
*
* TEST: C c = new C(); c.m() throws AME
*/
public void testReabstract() {
Interface I = new Interface("I", DefaultMethod.std("99"));
Interface J = new Interface("J", I, AbstractMethod.std());
Class C = new Class("C", J);
assertThrows(AbstractMethodError.class, C);
}
/**
* interface I { default int m() { return 88; } }
* interface J extends I { default int m() { return 99; } }
* class C implements J {}
*
* TEST: C c = new C(); c.m() == 99;
* TEST: J j = new C(); j.m() == 99;
* TEST: I i = new C(); i.m() == 99;
*/
public void testShadow() {
Interface I = new Interface("I", DefaultMethod.std("88"));
Interface J = new Interface("J", I, DefaultMethod.std("99"));
Class C = new Class("C", J);
assertInvokeVirtualEquals(99, C);
assertInvokeInterfaceEquals(99, C, J);
assertInvokeInterfaceEquals(99, C, I);
}
/**
* interface I { default int m() { return 88; } }
* interface J extends I { default int m() { return 99; } }
* class C implements I, J {}
*
* TEST: C c = new C(); c.m() == 99;
* TEST: J j = new C(); j.m() == 99;
* TEST: I i = new C(); i.m() == 99;
*/
public void testDisqualified() {
Interface I = new Interface("I", DefaultMethod.std("88"));
Interface J = new Interface("J", I, DefaultMethod.std("99"));
Class C = new Class("C", I, J);
assertInvokeVirtualEquals(99, C);
assertInvokeInterfaceEquals(99, C, J);
assertInvokeInterfaceEquals(99, C, I);
}
/**
* interface I<T> { default int m(T t) { return 99; } }
* Class C implements I<String> { public int m() { return 88; } }
*
* TEST: C c = new C(); c.m() == 88;
* TEST: I i = new C(); i.m() == 88;
*/
public void testSelfFill() {
// This test ensures that a concrete method overrides a default method
// that matches at the language-level, but has a different method
// signature due to erasure.
// debugTest();
DefaultMethod dm = new DefaultMethod(
"int", "m", "return 99;", new MethodParameter("T", "t"));
ConcreteMethod cm = new ConcreteMethod(
"int", "m", "return 88;", AccessFlag.PUBLIC,
new MethodParameter("String", "s"));
Interface I = new Interface("I", new TypeParameter("T"), dm);
Class C = new Class("C", I.with("String"), cm);
AbstractMethod pm = new AbstractMethod(
"int", "m", new MethodParameter("T", "t"));
assertInvokeVirtualEquals(new Integer(88), C, cm, "-1", "\"string\"");
assertInvokeInterfaceEquals(
new Integer(88), C, I.with("String"), pm, "\"string\"");
}
/**
* interface I { default int m() { return 99; } }
* class C implements I {}
*
* TEST: C.class.getMethod("m").invoke(new C()) == 99
*/
public void testReflectCall() {
Interface I = new Interface("I", DefaultMethod.std("99"));
Class C = new Class("C", I);
Compiler.Flags[] flags = this.verbose ?
new Compiler.Flags[] { Compiler.Flags.VERBOSE } :
new Compiler.Flags[] {};
Compiler compiler = new Compiler(flags);
java.lang.Class<?> cls = null;
try {
cls = compiler.compileAndLoad(C);
} catch (ClassNotFoundException e) {
fail("Could not load class");
}
java.lang.reflect.Method method = null;
try {
method = cls.getMethod(stdMethodName);
} catch (NoSuchMethodException e) {
fail("Could not find method in class");
}
assertNotNull(method);
Object c = null;
try {
c = cls.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
fail("Could not create instance of class");
}
assertNotNull(c);
Integer res = null;
try {
res = (Integer)method.invoke(c);
} catch (IllegalAccessException |
java.lang.reflect.InvocationTargetException e) {
fail("Could not invoke default instance method");
}
assertNotNull(res);
assertEquals(res.intValue(), 99);
compiler.cleanup();
}
/**
* interface I<T,V,W> { default int m(T t, V v, W w) { return 99; } }
* interface J<T,V> extends I<String,T,V> { int m(T t, V v, String w); } }
* interface K<T> extends J<String,T> { int m(T t, String v, String w); } }
* class C implements K<String> {
* public int m(String t, String v, String w) { return 88; }
* }
*
* TEST: I<String,String,String> i = new C(); i.m("A","B","C") == 88;
* TEST: J<String,String> j = new C(); j.m("A","B","C") == 88;
* TEST: K<String> k = new C(); k.m("A","B","C") == 88;
*/
public void testBridges() {
DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;",
new MethodParameter("T", "t"), new MethodParameter("V", "v"),
new MethodParameter("W", "w"));
AbstractMethod pm0 = new AbstractMethod("int", stdMethodName,
new MethodParameter("T", "t"), new MethodParameter("V", "v"),
new MethodParameter("W", "w"));
AbstractMethod pm1 = new AbstractMethod("int", stdMethodName,
new MethodParameter("T", "t"), new MethodParameter("V", "v"),
new MethodParameter("String", "w"));
AbstractMethod pm2 = new AbstractMethod("int", stdMethodName,
new MethodParameter("T", "t"), new MethodParameter("String", "v"),
new MethodParameter("String", "w"));
ConcreteMethod cm = new ConcreteMethod("int",stdMethodName,"return 88;",
AccessFlag.PUBLIC,
new MethodParameter("String", "t"),
new MethodParameter("String", "v"),
new MethodParameter("String", "w"));
Interface I = new Interface("I", new TypeParameter("T"),
new TypeParameter("V"), new TypeParameter("W"), dm);
Interface J = new Interface("J",
new TypeParameter("T"), new TypeParameter("V"),
I.with("String", "T", "V"), pm1);
Interface K = new Interface("K", new TypeParameter("T"),
J.with("String", "T"), pm2);
Class C = new Class("C", K.with("String"), cm);
String[] args = new String[] { "\"A\"", "\"B\"", "\"C\"" };
assertInvokeInterfaceEquals(new Integer(88), C,
I.with("String", "String", "String"), pm0, args);
assertInvokeInterfaceEquals(new Integer(88), C,
J.with("String", "String"), pm1, args);
assertInvokeInterfaceEquals(new Integer(88), C,
K.with("String"), pm2, args);
}
/**
* interface J { default int m() { return 88; } }
* interface I extends J { default int m() { return J.super.m(); } }
* class C implements I {}
*
* TEST: C c = new C(); c.m() == 88;
* TEST: I i = new C(); i.m() == 88;
*/
public void testSuperBasic() {
// debugTest();
Interface J = new Interface("J", DefaultMethod.std("88"));
Interface I = new Interface("I", J, new DefaultMethod(
"int", stdMethodName, "return J.super.m();"));
I.addCompilationDependency(J.findMethod(stdMethodName));
Class C = new Class("C", I);
assertInvokeVirtualEquals(88, C);
assertInvokeInterfaceEquals(88, C, I);
}
/**
* interface K { int m() default { return 99; } }
* interface L { int m() default { return 101; } }
* interface J extends K, L {}
* interface I extends J, K { int m() default { J.super.m(); } }
* class C implements I {}
*
* TEST: C c = new C(); c.m() throws AME
* TODO: add case for K k = new C(); k.m() throws AME
*/
public void testSuperConflict() {
// debugTest();
Interface K = new Interface("K", DefaultMethod.std("99"));
Interface L = new Interface("L", DefaultMethod.std("101"));
Interface J = new Interface("J", K, L);
Interface I = new Interface("I", J, K, new DefaultMethod(
"int", stdMethodName, "return J.super.m();"));
Interface Jstub = new Interface("J", DefaultMethod.std("-1"));
I.addCompilationDependency(Jstub);
I.addCompilationDependency(Jstub.findMethod(stdMethodName));
Class C = new Class("C", I);
assertThrows(AbstractMethodError.class, C);
}
/**
* interface I { default int m() { return 99; } }
* interface J extends I { default int m() { return 55; } }
* class C implements I, J { public int m() { return I.super.m(); } }
*
* TEST: C c = new C(); c.m() throws AME
* TODO: add case for J j = new C(); j.m() throws AME
*/
public void testSuperDisqual() {
Interface I = new Interface("I", DefaultMethod.std("99"));
Interface J = new Interface("J", I, DefaultMethod.std("55"));
Class C = new Class("C", I, J,
new ConcreteMethod("int", stdMethodName, "return I.super.m();",
AccessFlag.PUBLIC));
C.addCompilationDependency(I.findMethod(stdMethodName));
assertThrows(AbstractMethodError.class, C);
}
/**
* interface J { int m(); }
* interface I extends J { default int m() { return J.super.m(); } }
* class C implements I {}
*
* TEST: C c = new C(); c.m() throws AME
* TODO: add case for I i = new C(); i.m() throws AME
*/
public void testSuperNull() {
Interface J = new Interface("J", AbstractMethod.std());
Interface I = new Interface("I", J, new DefaultMethod(
"int", stdMethodName, "return J.super.m();"));
Interface Jstub = new Interface("J", DefaultMethod.std("99"));
I.addCompilationDependency(Jstub);
I.addCompilationDependency(Jstub.findMethod(stdMethodName));
Class C = new Class("C", I);
assertThrows(AbstractMethodError.class, C);
}
/**
* interface J<T> { default int m(T t) { return 88; } }
* interface I extends J<String> {
* int m(String s) default { return J.super.m(); }
* }
* class C implements I {}
*
* TEST: I i = new C(); i.m("") == 88;
*/
public void testSuperGeneric() {
Interface J = new Interface("J", new TypeParameter("T"),
new DefaultMethod("int", stdMethodName, "return 88;",
new MethodParameter("T", "t")));
Interface I = new Interface("I", J.with("String"),
new DefaultMethod("int", stdMethodName, "return J.super.m(s);",
new MethodParameter("String", "s")));
I.addCompilationDependency(J.findMethod(stdMethodName));
Class C = new Class("C", I);
AbstractMethod pm = new AbstractMethod("int", stdMethodName,
new MethodParameter("String", "s"));
assertInvokeInterfaceEquals(
new Integer(88), C, new Extends(I), pm, "\"\"");
}
/**
* interface I<T> { int m(T t) default { return 44; } }
* interface J extends I<String> { int m(String s) default { return 55; } }
* class C implements I<String>, J {
* public int m(String s) { return I.super.m(s); }
* }
*
* TEST: C c = new C(); c.m("string") throws AME
*/
public void testSuperGenericDisqual() {
MethodParameter t = new MethodParameter("T", "t");
MethodParameter s = new MethodParameter("String", "s");
Interface I = new Interface("I", new TypeParameter("T"),
new DefaultMethod("int", stdMethodName, "return 44;", t));
Interface J = new Interface("J", I.with("String"),
new DefaultMethod("int", stdMethodName, "return 55;", s));
Class C = new Class("C", I.with("String"), J,
new ConcreteMethod("int", stdMethodName,
"return I.super.m(s);", AccessFlag.PUBLIC, s));
C.addCompilationDependency(I.findMethod(stdMethodName));
assertThrows(AbstractMethodError.class, C,
new ConcreteMethod(
"int", stdMethodName, "return -1;", AccessFlag.PUBLIC, s),
"-1", "\"string\"");
}
/**
* interface I { default Integer m() { return new Integer(88); } }
* class C { Number m() { return new Integer(99); } }
* class D extends C implements I {}
* class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger;
* TEST: S s = new S(); s.foo() == new Integer(99)
*/
public void testCovarBridge() {
Interface I = new Interface("I", new DefaultMethod(
"Integer", "m", "return new Integer(88);"));
Class C = new Class("C", new ConcreteMethod(
"Number", "m", "return new Integer(99);", AccessFlag.PUBLIC));
Class D = new Class("D", I, C);
ConcreteMethod DstubMethod = new ConcreteMethod(
"Integer", "m", "return null;", AccessFlag.PUBLIC);
Class Dstub = new Class("D", DstubMethod);
ConcreteMethod toCall = new ConcreteMethod(
"Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC);
Class S = new Class("S", D, toCall);
S.addCompilationDependency(Dstub);
S.addCompilationDependency(DstubMethod);
assertInvokeVirtualEquals(new Integer(99), S, toCall, "null");
}
/**
* interface I { default Integer m() { return new Integer(88); } }
* class C { int m() { return 99; } }
* class D extends C implements I {}
* class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger;
* TEST: S s = new S(); s.foo() == new Integer(88)
*/
public void testNoCovarNoBridge() {
Interface I = new Interface("I", new DefaultMethod(
"Integer", "m", "return new Integer(88);"));
Class C = new Class("C", new ConcreteMethod(
"int", "m", "return 99;", AccessFlag.PUBLIC));
Class D = new Class("D", I, C);
ConcreteMethod DstubMethod = new ConcreteMethod(
"Integer", "m", "return null;", AccessFlag.PUBLIC);
Class Dstub = new Class("D", DstubMethod);
ConcreteMethod toCall = new ConcreteMethod(
"Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC);
Class S = new Class("S", D, toCall);
S.addCompilationDependency(Dstub);
S.addCompilationDependency(DstubMethod);
assertInvokeVirtualEquals(new Integer(88), S, toCall, "null");
}
/**
* interface J { int m(); }
* interface I extends J { default int m() { return 99; } }
* class B implements J {}
* class C extends B implements I {}
* TEST: C c = new C(); c.m() == 99
*
* The point of this test is that B does not get default method analysis,
* and C does not generate any new miranda methods in the vtable.
* It verifies that default method analysis occurs when mirandas have been
* inherited and the supertypes don't have any overpass methods.
*/
public void testNoNewMiranda() {
Interface J = new Interface("J", AbstractMethod.std());
Interface I = new Interface("I", J, DefaultMethod.std("99"));
Class B = new Class("B", J);
Class C = new Class("C", B, I);
assertInvokeVirtualEquals(99, C);
}
/**
* interface I<T,V,W> { int m(T t, V v, W w); }
* interface J<T,V> implements I<T,V,String> { int m(T t, V v, String w); }
* interface K<T> implements J<T,String> {
* int m(T t, String v, String w); { return 99; } }
* class C implements K<String> {
* public int m(Object t, Object v, String w) { return 77; }
* }
* TEST C = new C(); ((I)c).m(Object,Object,Object) == 99
* TEST C = new C(); ((J)c).m(Object,Object,String) == 77
* TEST C = new C(); ((K)c).m(Object,String,String) == 99
*
* Test that a erased-signature-matching method does not implement
* non-language-level matching methods
*/
public void testNonConcreteFill() {
AbstractMethod ipm = new AbstractMethod("int", "m",
new MethodParameter("T", "t"),
new MethodParameter("V", "s"),
new MethodParameter("W", "w"));
Interface I = new Interface("I",
new TypeParameter("T"),
new TypeParameter("V"),
new TypeParameter("W"), ipm);
AbstractMethod jpm = new AbstractMethod("int", "m",
new MethodParameter("T", "t"),
new MethodParameter("V", "s"),
new MethodParameter("String", "w"));
Interface J = new Interface("J",
new TypeParameter("T"),
new TypeParameter("V"),
I.with("T", "V", "String"), jpm);
AbstractMethod kpm = new AbstractMethod("int", "m",
new MethodParameter("T", "t"),
new MethodParameter("String", "s"),
new MethodParameter("String", "w"));
Interface K = new Interface("K",
new TypeParameter("T"),
J.with("T", "String"),
new DefaultMethod("int", "m", "return 99;",
new MethodParameter("T", "t"),
new MethodParameter("String", "v"),
new MethodParameter("String", "w")));
Class C = new Class("C",
K.with("String"),
new ConcreteMethod("int", "m", "return 77;",
AccessFlag.PUBLIC,
new MethodParameter("Object", "t"),
new MethodParameter("Object", "v"),
new MethodParameter("String", "w")));
String a = "\"\"";
assertInvokeInterfaceEquals(99, C,
K.with("String"), kpm, a, a, a);
assertInvokeInterfaceEquals(77, C,
J.with("String", "String"), jpm, a, a, a);
assertInvokeInterfaceEquals(99, C,
I.with("String", "String", "String"), ipm, a, a, a);
}
public void testStrictfpDefault() {
try {
java.lang.Class.forName("org.openjdk.tests.vm.StrictfpDefault");
} catch (Exception e) {
fail("Could not load class", e);
}
}
public void testSynchronizedDefault() {
try {
java.lang.Class.forName("org.openjdk.tests.vm.SynchronizedDefault");
} catch (Exception e) {
fail("Could not load class", e);
}
}
}
interface StrictfpDefault {
default strictfp void m() {}
}
interface SynchronizedDefault {
default synchronized void m() {}
}

View file

@ -0,0 +1,197 @@
/*
* Copyright (c) 2012 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package org.openjdk.tests.vm;
import java.util.*;
import org.testng.ITestResult;
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.openjdk.tests.separate.*;
import org.openjdk.tests.separate.Compiler;
import org.openjdk.tests.shapegen.Hierarchy;
import org.openjdk.tests.shapegen.HierarchyGenerator;
import org.openjdk.tests.shapegen.ClassCase;
import static org.testng.Assert.*;
import static org.openjdk.tests.separate.SourceModel.*;
import static org.openjdk.tests.separate.SourceModel.Class;
import static org.openjdk.tests.separate.SourceModel.Method;
import static org.openjdk.tests.separate.SourceModel.Type;
public class FDSeparateCompilationTest extends TestHarness {
private static String EMPTY = "\"\"";
public FDSeparateCompilationTest() {
super(false, true);
}
@DataProvider(name = "allShapes", parallel = true)
public Object[][] hierarchyGenerator() {
ArrayList<Object[]> allCases = new ArrayList<>();
HierarchyGenerator hg = new HierarchyGenerator();
for (Object x : hg.getOK()) {
allCases.add(new Object[]{x});
}
for (Object x : hg.getErr()) {
allCases.add(new Object[]{x});
}
return allCases.toArray(new Object[0][]);
}
// The expected value obtained when invoking the method from the specified
// class. If returns null, then an AbstractMethodError is expected.
private static String getExpectedResult(ClassCase cc) {
Set<ClassCase> provs = cc.get_mprov();
if (cc.get_mres() != null) {
return cc.get_mres().getName();
} else if (provs != null && provs.size() == 1) {
ClassCase cand = provs.iterator().next();
switch (cand.kind) {
case CCONCRETE:
case IDEFAULT:
return cand.getName();
case CNONE:
case IVAC:
return getExpectedResult(cand);
}
}
return null;
}
private static final ConcreteMethod canonicalMethod = new ConcreteMethod(
"String", "m", "returns " + EMPTY + ";", AccessFlag.PUBLIC);
@Test(groups = "vm", dataProvider = "allShapes")
public void separateCompilationTest(Hierarchy hs) {
ClassCase cc = hs.root;
Type type = sourceTypeFrom(hs.root);
Class specimen = null;
if (type instanceof Class) {
Class ctype = (Class)type;
if (ctype.isAbstract()) {
specimen = new Class("Test" + ctype.getName(), ctype);
} else {
specimen = ctype;
}
} else {
specimen = new Class("Test" + type.getName(), (Interface)type);
}
String value = getExpectedResult(cc);
if (value != null) {
assertInvokeVirtualEquals(value, specimen, canonicalMethod, EMPTY);
} else {
assertThrows(AbstractMethodError.class, specimen,
canonicalMethod, EMPTY);
}
}
@AfterMethod
public void printCaseError(ITestResult result) {
if (result.getStatus() == ITestResult.FAILURE) {
Hierarchy hs = (Hierarchy)result.getParameters()[0];
System.out.println("Separate compilation case " + hs);
printCaseDetails(hs);
}
}
@AfterSuite
public void cleanupCompilerCache() {
Compiler.purgeCache();
}
private void printCaseDetails(Hierarchy hs) {
String exp = getExpectedResult(hs.root);
for (String s : hs.getDescription()) {
System.out.println(" " + s);
}
if (exp != null) {
System.out.println(" Expected \"" + exp + "\"");
} else {
System.out.println(" Expected AbstractMethodError");
}
}
private Type sourceTypeFrom(ClassCase cc) {
Type type = null;
if (cc.isInterface()) {
Interface iface = new Interface(cc.getName());
for (ClassCase scc : cc.getInterfaces()) {
Interface supertype = (Interface)sourceTypeFrom(scc);
iface.addSuperType(supertype);
}
type = iface;
} else {
Class cls = new Class(cc.getName());
if (cc.hasSuperclass()) {
Class superc = (Class)sourceTypeFrom(cc.getSuperclass());
cls.setSuperClass(superc);
}
for (ClassCase scc : cc.getInterfaces()) {
Interface supertype = (Interface)sourceTypeFrom(scc);
cls.addSuperType(supertype);
}
if (cc.isAbstract()) {
cls.getAccessFlags().add(AccessFlag.ABSTRACT);
}
type = cls;
}
Method method = methodFrom(cc);
if (method != null) {
type.addMethod(method);
}
return type;
}
private Method methodFrom(ClassCase cc) {
switch (cc.kind) {
case IVAC:
case CNONE: return null;
case IPRESENT:
case CABSTRACT:
return new AbstractMethod("String", "m", AccessFlag.PUBLIC);
case IDEFAULT:
return new DefaultMethod(
"String", "m", "return \"" + cc.getName() + "\";");
case CCONCRETE:
return new ConcreteMethod(
"String", "m", "return \"" + cc.getName() + "\";",
AccessFlag.PUBLIC);
default:
fail("Unknown method type in class");
return null;
}
}
}