mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-16 00:54:38 +02:00
8003639: convert lambda testng tests to jtreg and add them
Reviewed-by: mcimadamore
This commit is contained in:
parent
d1eede168b
commit
d1a78e2021
48 changed files with 6900 additions and 252 deletions
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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); };
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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:*");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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)");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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)");
|
||||||
|
}
|
||||||
|
***/
|
||||||
|
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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:*");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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:*");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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('@'), '@');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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*");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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*");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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*");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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*");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
2
langtools/test/tools/javac/lambdaShapes/TEST.properties
Normal file
2
langtools/test/tools/javac/lambdaShapes/TEST.properties
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
TestNG.dirs = tools/javac/lambdaShapes
|
||||||
|
|
|
@ -21,14 +21,12 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
package org.openjdk.tests.javac;
|
||||||
* @test
|
|
||||||
* @summary Automatic test for checking correctness of default resolution
|
|
||||||
*/
|
|
||||||
|
|
||||||
import shapegen.*;
|
import org.openjdk.tests.shapegen.*;
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
import com.sun.source.util.JavacTask;
|
||||||
|
import com.sun.tools.javac.util.Pair;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -43,9 +41,14 @@ import javax.tools.SimpleJavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
import javax.tools.StandardJavaFileManager;
|
||||||
import javax.tools.ToolProvider;
|
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 {
|
public class FDTest {
|
||||||
|
|
||||||
enum TestKind {
|
public enum TestKind {
|
||||||
POSITIVE,
|
POSITIVE,
|
||||||
NEGATIVE;
|
NEGATIVE;
|
||||||
|
|
||||||
|
@ -55,17 +58,58 @@ public class FDTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static JavaCompiler comp;
|
||||||
//create default shared JavaCompiler - reused across multiple compilations
|
public static StandardJavaFileManager fm;
|
||||||
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
|
||||||
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
|
||||||
|
|
||||||
|
@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();
|
HierarchyGenerator hg = new HierarchyGenerator();
|
||||||
for (TestKind tk : TestKind.values()) {
|
for (TestKind tk : TestKind.values()) {
|
||||||
for (Hierarchy hs : tk.getHierarchy(hg)) {
|
for (Hierarchy hs : tk.getHierarchy(hg)) {
|
||||||
new FDTest(tk, hs).run(comp, fm);
|
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;
|
TestKind tk;
|
||||||
|
@ -73,6 +117,8 @@ public class FDTest {
|
||||||
DefenderTestSource source;
|
DefenderTestSource source;
|
||||||
DiagnosticChecker diagChecker;
|
DiagnosticChecker diagChecker;
|
||||||
|
|
||||||
|
public FDTest() {}
|
||||||
|
|
||||||
FDTest(TestKind tk, Hierarchy hs) {
|
FDTest(TestKind tk, Hierarchy hs) {
|
||||||
this.tk = tk;
|
this.tk = tk;
|
||||||
this.hs = hs;
|
this.hs = hs;
|
||||||
|
@ -86,7 +132,7 @@ public class FDTest {
|
||||||
try {
|
try {
|
||||||
ct.analyze();
|
ct.analyze();
|
||||||
} catch (Throwable ex) {
|
} 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();
|
check();
|
||||||
}
|
}
|
||||||
|
@ -94,11 +140,11 @@ public class FDTest {
|
||||||
void check() {
|
void check() {
|
||||||
boolean errorExpected = tk == TestKind.NEGATIVE;
|
boolean errorExpected = tk == TestKind.NEGATIVE;
|
||||||
if (errorExpected != diagChecker.errorFound) {
|
if (errorExpected != diagChecker.errorFound) {
|
||||||
throw new AssertionError("problem in source: \n" +
|
fail("problem in source: \n" +
|
||||||
"\nerror found = " + diagChecker.errorFound +
|
"\nerror found = " + diagChecker.errorFound +
|
||||||
"\nerror expected = " + errorExpected +
|
"\nerror expected = " + errorExpected +
|
||||||
"\n" + dumpHierarchy() +
|
"\n" + dumpHierarchy() +
|
||||||
"\n" + source.getCharContent(true));
|
"\n" + source.getCharContent(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +169,7 @@ public class FDTest {
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
List<ClassCase> defaultRef = new ArrayList<>();
|
List<ClassCase> defaultRef = new ArrayList<>();
|
||||||
for (ClassCase cc : hs.all) {
|
for (ClassCase cc : hs.all) {
|
||||||
hs.genClassDef(buf, cc, null, defaultRef);
|
Hierarchy.genClassDef(buf, cc, null, defaultRef);
|
||||||
}
|
}
|
||||||
source = buf.toString();
|
source = buf.toString();
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
};
|
|
@ -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);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package shapegen;
|
package org.openjdk.tests.shapegen;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -52,6 +52,8 @@ public class ClassCase {
|
||||||
this.isInterface = isInterface;
|
this.isInterface = isInterface;
|
||||||
this.prefix = prefix;
|
this.prefix = prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPrefix() { return prefix; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Kind kind;
|
public final Kind kind;
|
||||||
|
@ -67,7 +69,7 @@ public class ClassCase {
|
||||||
private ClassCase _mres;
|
private ClassCase _mres;
|
||||||
private ClassCase _mdefend;
|
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) {
|
public ClassCase(Kind kind, ClassCase superclass, List<ClassCase> interfaces) {
|
||||||
this.kind = kind;
|
this.kind = kind;
|
|
@ -23,14 +23,16 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package shapegen;
|
package org.openjdk.tests.shapegen;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static shapegen.ClassCase.Kind.*;
|
import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -67,15 +69,15 @@ public class Hierarchy {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void genInterfaceList(StringBuilder buf, String prefix, List<ClassCase> interfaces) {
|
private static void genInterfaceList(StringBuilder buf, String prefix, List<ClassCase> interfaces) {
|
||||||
if (!interfaces.isEmpty()) {
|
if (!interfaces.isEmpty()) {
|
||||||
buf.append(" ");
|
buf.append(" ");
|
||||||
buf.append(prefix);
|
buf.append(prefix);
|
||||||
buf.append(" ");
|
buf.append(" ");
|
||||||
buf.append(interfaces.get(0));
|
buf.append(interfaces.get(0));
|
||||||
for (int i = 1; i < interfaces.size(); ++i) {
|
for (int i = 1; i < interfaces.size(); ++i) {
|
||||||
buf.append(", " + interfaces.get(i));
|
buf.append(", " + interfaces.get(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void genClassDef(StringBuilder buf, ClassCase cc, String implClass, List<ClassCase> defaultRef) {
|
public static void genClassDef(StringBuilder buf, ClassCase cc, String implClass, List<ClassCase> defaultRef) {
|
||||||
|
@ -140,4 +142,68 @@ public class Hierarchy {
|
||||||
return root.getName();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -23,9 +23,9 @@
|
||||||
* questions.
|
* 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.Collection;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -34,7 +34,7 @@ import java.util.Collections;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static shapegen.ClassCase.Kind.*;
|
import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
|
||||||
|
|
||||||
import static java.lang.Math.pow;
|
import static java.lang.Math.pow;
|
||||||
|
|
||||||
|
@ -44,10 +44,10 @@ import static java.lang.Math.pow;
|
||||||
*/
|
*/
|
||||||
public final class HierarchyGenerator {
|
public final class HierarchyGenerator {
|
||||||
|
|
||||||
private static int okcnt = 0;
|
private int okcnt = 0;
|
||||||
private static int errcnt = 0;
|
private int errcnt = 0;
|
||||||
private static Set<Hierarchy> uniqueOK = new HashSet<>();
|
private Set<Hierarchy> uniqueOK = new HashSet<>();
|
||||||
private static Set<Hierarchy> uniqueErr = new HashSet<>();
|
private Set<Hierarchy> uniqueErr = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param args the command line arguments
|
* @param args the command line arguments
|
||||||
|
@ -71,7 +71,7 @@ public final class HierarchyGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void organize(String tname, List<Hierarchy> totest) {
|
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;
|
int nodefault = 0;
|
||||||
List<Hierarchy> ok = new ArrayList<>();
|
List<Hierarchy> ok = new ArrayList<>();
|
||||||
List<Hierarchy> err = new ArrayList<>();
|
List<Hierarchy> err = new ArrayList<>();
|
||||||
|
@ -152,12 +152,14 @@ public final class HierarchyGenerator {
|
||||||
return totest;
|
return totest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final List<ClassCase> EMPTY_LIST = new ArrayList<>();
|
||||||
|
|
||||||
private List<ClassCase> iList(Kind kind) {
|
private List<ClassCase> iList(Kind kind) {
|
||||||
if (kind == null) {
|
if (kind == null) {
|
||||||
return Collections.EMPTY_LIST;
|
return EMPTY_LIST;
|
||||||
} else {
|
} else {
|
||||||
List<ClassCase> itfs = new ArrayList<>();
|
List<ClassCase> itfs = new ArrayList<>();
|
||||||
itfs.add(new ClassCase(kind, null, Collections.EMPTY_LIST));
|
itfs.add(new ClassCase(kind, null, EMPTY_LIST));
|
||||||
return itfs;
|
return itfs;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,7 +23,7 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package shapegen;
|
package org.openjdk.tests.shapegen;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
|
@ -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);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
|
@ -23,15 +23,15 @@
|
||||||
* questions.
|
* 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.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static shapegen.ClassCase.Kind.*;
|
import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type Template Node
|
* Type Template Node
|
|
@ -23,7 +23,7 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package shapegen;
|
package org.openjdk.tests.shapegen;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
|
@ -23,7 +23,7 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package shapegen;
|
package org.openjdk.tests.shapegen;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
|
@ -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() {}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue