8003639: convert lambda testng tests to jtreg and add them
Reviewed-by: mcimadamore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethodExecution/DefaultMethodRegressionTests.java Tue Nov 20 09:58:55 2012 -0800
@@ -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");
+ }
+ }
+}
--- a/langtools/test/tools/javac/defaultMethods/fd/FDTest.java Tue Nov 20 15:43:28 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +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.
- *
- * 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
- * @summary Automatic test for checking correctness of default resolution
- */
-
-import shapegen.*;
-
-import com.sun.source.util.JavacTask;
-
-import java.net.URI;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
-
-public class FDTest {
-
- enum TestKind {
- POSITIVE,
- NEGATIVE;
-
- Collection<Hierarchy> getHierarchy(HierarchyGenerator hg) {
- return this == POSITIVE ?
- hg.getOK() : hg.getErr();
- }
- }
-
- public static void main(String[] args) throws Exception {
- //create default shared JavaCompiler - reused across multiple compilations
- JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
- StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
-
- HierarchyGenerator hg = new HierarchyGenerator();
- for (TestKind tk : TestKind.values()) {
- for (Hierarchy hs : tk.getHierarchy(hg)) {
- new FDTest(tk, hs).run(comp, fm);
- }
- }
- }
-
- TestKind tk;
- Hierarchy hs;
- DefenderTestSource source;
- DiagnosticChecker diagChecker;
-
- FDTest(TestKind tk, Hierarchy hs) {
- this.tk = tk;
- this.hs = hs;
- this.source = new DefenderTestSource();
- this.diagChecker = new DiagnosticChecker();
- }
-
- void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
- JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
- null, null, Arrays.asList(source));
- try {
- ct.analyze();
- } catch (Throwable ex) {
- throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
- }
- check();
- }
-
- void check() {
- boolean errorExpected = tk == TestKind.NEGATIVE;
- if (errorExpected != diagChecker.errorFound) {
- throw new AssertionError("problem in source: \n" +
- "\nerror found = " + diagChecker.errorFound +
- "\nerror expected = " + errorExpected +
- "\n" + dumpHierarchy() +
- "\n" + source.getCharContent(true));
- }
- }
-
- String dumpHierarchy() {
- StringBuilder buf = new StringBuilder();
- buf.append("root = " + hs.root + "\n");
- for (ClassCase cc : hs.all) {
- buf.append(" class name = " + cc.getName() + "\n");
- buf.append(" class OK = " + cc.get_OK() + "\n");
- buf.append(" prov = " + cc.get_mprov() + "\n");
-
- }
- return buf.toString();
- }
-
- class DefenderTestSource extends SimpleJavaFileObject {
-
- String source;
-
- public DefenderTestSource() {
- super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
- StringBuilder buf = new StringBuilder();
- List<ClassCase> defaultRef = new ArrayList<>();
- for (ClassCase cc : hs.all) {
- hs.genClassDef(buf, cc, null, defaultRef);
- }
- source = buf.toString();
- }
-
- @Override
- public CharSequence getCharContent(boolean ignoreEncodingErrors) {
- return source;
- }
- }
-
- static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
-
- boolean errorFound;
-
- public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
- if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
- errorFound = true;
- }
- }
- }
-}
--- a/langtools/test/tools/javac/defaultMethods/fd/shapegen/ClassCase.java Tue Nov 20 15:43:28 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +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.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- *
- * @author Robert Field
- */
-public class ClassCase {
-
- public enum Kind {
- IVAC (true, "v"),
- IPRESENT (true, "p"),
- IDEFAULT (true, "d"),
- CNONE (false, "n"),
- CABSTRACT (false, "a"),
- CCONCRETE (false, "c");
-
- private final String prefix;
- public final boolean isInterface;
-
- Kind(boolean isInterface, String prefix) {
- this.isInterface = isInterface;
- this.prefix = prefix;
- }
- }
-
- public final Kind kind;
- private final ClassCase superclass;
- private final List<ClassCase> supertypes;
-
- private String name;
- private boolean _OK;
- private boolean _HasClassMethod;
- private Set<ClassCase> _mprov;
- private boolean _IsConcrete;
- private boolean _HasDefault;
- private ClassCase _mres;
- private ClassCase _mdefend;
-
- private Set<RuleGroup> executed = new HashSet<RuleGroup>() {};
-
- public ClassCase(Kind kind, ClassCase superclass, List<ClassCase> interfaces) {
- this.kind = kind;
- this.superclass = superclass;
-
- // Set supertypes from superclass (if any) and interfaces
- List<ClassCase> lc;
- if (superclass == null) {
- lc = interfaces;
- } else {
- lc = new ArrayList<>();
- lc.add(superclass);
- lc.addAll(interfaces);
- }
- this.supertypes = lc;
- }
-
- public final boolean isInterface() { return kind.isInterface; }
- public final boolean isClass() { return !kind.isInterface; }
-
- public Set<ClassCase> get_mprov() {
- exec(RuleGroup.PROVENENCE);
- return _mprov;
- }
-
- public void set_mprov(ClassCase cc) {
- Set<ClassCase> s = new HashSet<>();
- s.add(cc);
- _mprov = s;
- }
-
- public void set_mprov(Set<ClassCase> s) {
- _mprov = s;
- }
-
- public ClassCase get_mres() {
- exec(RuleGroup.RESOLUTION);
- return _mres;
- }
-
- public void set_mres(ClassCase cc) {
- _mres = cc;
- }
-
- public ClassCase get_mdefend() {
- exec(RuleGroup.DEFENDER);
- return _mdefend;
- }
-
- public void set_mdefend(ClassCase cc) {
- _mdefend = cc;
- }
-
- public boolean get_HasClassMethod() {
- exec(RuleGroup.PROVENENCE);
- return _HasClassMethod;
- }
-
- public void set_HasClassMethod(boolean bool) {
- _HasClassMethod = bool;
- }
-
- public boolean get_HasDefault() {
- exec(RuleGroup.MARKER);
- return _HasDefault;
- }
-
- public void set_HasDefault(boolean bool) {
- _HasDefault = bool;
- }
-
- public boolean get_IsConcrete() {
- exec(RuleGroup.MARKER);
- return _IsConcrete;
- }
-
- public void set_IsConcrete(boolean bool) {
- _IsConcrete = bool;
- }
-
- public boolean get_OK() {
- exec(RuleGroup.CHECKING);
- return _OK;
- }
-
- public void set_OK(boolean bool) {
- _OK = bool;
- }
-
- public boolean isMethodDefined() {
- for (ClassCase cc : supertypes) {
- if (cc.isMethodDefined()) {
- return true;
- }
- }
- switch (kind) {
- case CCONCRETE:
- case CABSTRACT:
- case IPRESENT:
- case IDEFAULT:
- return true;
- default:
- return false;
- }
- }
-
- public boolean isAbstract() {
- return isMethodDefined() && (get_mres()==null);
- }
-
- public boolean hasSuperclass() {
- return superclass != null;
- }
-
- public ClassCase getSuperclass() {
- return superclass;
- }
-
- public List<ClassCase> getSupertypes() {
- return supertypes;
- }
-
- public List<ClassCase> getInterfaces() {
- if (superclass != null) {
- if (supertypes.get(0) != superclass) {
- throw new AssertionError("superclass missing from supertypes");
- }
- return supertypes.subList(1, supertypes.size());
- } else {
- return supertypes;
- }
- }
-
- public boolean isSubtypeOf(ClassCase cc) {
- // S-Refl
- if (cc.equals(this)) {
- return true;
- }
-
- // S-Def
- for (ClassCase sp : getSupertypes()) {
- if (cc.equals(sp)) {
- return true;
- }
- }
-
- // _S-Trans
- for (ClassCase sp : getSupertypes()) {
- if (sp.isSubtypeOf(cc)) {
- return true;
- }
- }
-
- return false;
- }
-
- public void init(Map<String, Integer> namingContext) {
- if (name != null) {
- return; // Already inited
- }
-
- for (ClassCase sup : supertypes) {
- sup.init(namingContext);
- }
-
- // Build name
- StringBuilder sb = new StringBuilder();
- if (!supertypes.isEmpty()) {
- sb.append(isInterface() ? "I" : "C");
- for (ClassCase cc : supertypes) {
- sb.append(cc.getName());
- }
- sb.append(kind.isInterface ? "i" : "c");
- }
- sb.append(kind.prefix);
- String pname = sb.toString();
- Integer icnt = namingContext.get(pname);
- int cnt = icnt == null ? 0 : icnt;
- ++cnt;
- namingContext.put(pname, cnt);
- if (cnt > 1) {
- sb.append(cnt);
- }
- this.name = sb.toString();
- }
-
- public boolean isa(Kind... kinds) {
- for (Kind k : kinds) {
- if (kind == k) {
- return true;
- }
- }
- return false;
- }
-
- private void exec(RuleGroup rg ) {
- if (!executed.contains(rg)) {
- rg.exec(this);
- executed.add(rg);
- }
- }
-
- public void collectClasses(Set<ClassCase> seen) {
- seen.add(this);
- for (ClassCase cc : supertypes) {
- cc.collectClasses(seen);
- }
- }
-
- public String getID() {
- if (name == null) {
- throw new Error("Access to uninitialized ClassCase");
- } else {
- return name;
- }
- }
-
- public final String getName() {
- if (name == null) {
- return "ClassCase uninited@" + hashCode();
- } else {
- return name;
- }
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj instanceof ClassCase && getID().equals(((ClassCase)obj).getID());
- }
-
- @Override
- public int hashCode() {
- return getID().hashCode();
- }
-
- @Override
- public String toString() {
- return getName();
- }
-}
--- a/langtools/test/tools/javac/defaultMethods/fd/shapegen/Hierarchy.java Tue Nov 20 15:43:28 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +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.List;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-import static shapegen.ClassCase.Kind.*;
-
-/**
- *
- * @author Robert Field
- */
-public class Hierarchy {
-
- public final ClassCase root;
- public final Set<ClassCase> all;
-
- public Hierarchy(ClassCase root) {
- this.root = root;
- root.init(new HashMap<String,Integer>());
- Set<ClassCase> allClasses = new HashSet<>();
- root.collectClasses(allClasses);
- this.all = allClasses;
- }
-
- public boolean anyDefaults() {
- for (ClassCase cc : all) {
- if (cc.kind == IDEFAULT) {
- return true;
- }
- }
- return false;
- }
-
- public boolean get_OK() {
- return root.get_OK();
- }
-
- public String testName() {
- return root + "Test";
- }
-
- private static void genInterfaceList(StringBuilder buf, String prefix, List<ClassCase> interfaces) {
- if (!interfaces.isEmpty()) {
- buf.append(" ");
- buf.append(prefix);
- buf.append(" ");
- buf.append(interfaces.get(0));
- for (int i = 1; i < interfaces.size(); ++i) {
- buf.append(", " + interfaces.get(i));
- }
- }
- }
-
- public static void genClassDef(StringBuilder buf, ClassCase cc, String implClass, List<ClassCase> defaultRef) {
- if (cc.isInterface()) {
- buf.append("interface ");
- buf.append(cc.getName() + " ");
- genInterfaceList(buf, "extends", cc.getInterfaces());
- buf.append(" {\n");
-
- switch (cc.kind) {
- case IDEFAULT:
- buf.append(" default String m() { return \"\"; }\n");
- defaultRef.add(cc);
- break;
- case IPRESENT:
- buf.append(" String m();\n");
- break;
- case IVAC:
- break;
- default:
- throw new AssertionError("Unexpected kind");
- }
- buf.append("}\n\n");
- } else {
- buf.append((cc.isAbstract()? "abstract " : ""));
- buf.append(" class " + cc.getName());
- if (cc.getSuperclass() != null) {
- buf.append(" extends " + cc.getSuperclass());
- }
-
- genInterfaceList(buf, "implements", cc.getInterfaces());
- buf.append(" {\n");
-
- switch (cc.kind) {
- case CCONCRETE:
- buf.append(" public String m() { return \"\"; }\n");
- break;
- case CABSTRACT:
- buf.append(" public abstract String m();\n");
- break;
- case CNONE:
- break;
- default:
- throw new AssertionError("Unexpected kind");
- }
- buf.append("}\n\n");
- }
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj instanceof Hierarchy && root.getID().equals(((Hierarchy)obj).root.getID());
- }
-
- @Override
- public int hashCode() {
- return root.getID().hashCode();
- }
-
- @Override
- public String toString() {
- return root.getName();
- }
-
-}
--- a/langtools/test/tools/javac/defaultMethods/fd/shapegen/HierarchyGenerator.java Tue Nov 20 15:43:28 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +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 shapegen.ClassCase.Kind;
-
-import java.util.Collection;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Collections;
-import java.util.ArrayList;
-import java.util.List;
-
-import static shapegen.ClassCase.Kind.*;
-
-import static java.lang.Math.pow;
-
-/**
- *
- * @author Robert Field
- */
-public final class HierarchyGenerator {
-
- private static int okcnt = 0;
- private static int errcnt = 0;
- private static Set<Hierarchy> uniqueOK = new HashSet<>();
- private static Set<Hierarchy> uniqueErr = new HashSet<>();
-
- /**
- * @param args the command line arguments
- */
- public HierarchyGenerator() {
- organize("exhaustive interface", iExhaustive(2));
- organize("exhaustive class", cExhaustive());
- organize("shapes interface", iShapes());
- organize("shapes class/interface", ciShapes());
-
- System.out.printf("\nExpect OK: %d -- unique %d", okcnt, uniqueOK.size());
- System.out.printf("\nExpect Error: %d -- unique %d\n", errcnt, uniqueErr.size());
- }
-
- public Collection<Hierarchy> getOK() {
- return uniqueOK;
- }
-
- public Collection<Hierarchy> getErr() {
- return uniqueErr;
- }
-
- private void organize(String tname, List<Hierarchy> totest) {
- System.out.printf("\nTesting %s....\n", tname);
- int nodefault = 0;
- List<Hierarchy> ok = new ArrayList<>();
- List<Hierarchy> err = new ArrayList<>();
- for (Hierarchy cc : totest) {
- if (cc.anyDefaults()) {
- //System.out.printf(" %s\n", cc);
- if (cc.get_OK()) {
- ok.add(cc);
- } else {
- err.add(cc);
- }
- } else {
- ++nodefault;
- }
- }
-
- errcnt += err.size();
- okcnt += ok.size();
- uniqueErr.addAll(err);
- uniqueOK.addAll(ok);
-
- System.out.printf(" %5d No default\n %5d Error\n %5d OK\n %5d Total\n",
- nodefault, err.size(), ok.size(), totest.size());
- }
-
- public List<Hierarchy> iExhaustive(int idepth) {
- List<ClassCase> current = new ArrayList<>();
- for (int i = 0; i < idepth; ++i) {
- current = ilayer(current);
- }
- return wrapInClassAndHierarchy(current);
- }
-
- private List<ClassCase> ilayer(List<ClassCase> srcLayer) {
- List<ClassCase> lay = new ArrayList<>();
- for (int i = (int) pow(2, srcLayer.size()) - 1; i >= 0; --i) {
- List<ClassCase> itfs = new ArrayList<>();
- for (int b = srcLayer.size() - 1; b >= 0; --b) {
- if ((i & (1<<b)) != 0) {
- itfs.add(srcLayer.get(b));
- }
- }
- lay.add(new ClassCase(IVAC, null, itfs));
- lay.add(new ClassCase(IPRESENT, null, itfs));
- lay.add(new ClassCase(IDEFAULT, null, itfs));
- lay.add(new ClassCase(IDEFAULT, null, itfs));
- }
- return lay;
- }
-
- public List<Hierarchy> cExhaustive() {
- final Kind[] iKinds = new Kind[]{IDEFAULT, IVAC, IPRESENT, null};
- final Kind[] cKinds = new Kind[]{CNONE, CABSTRACT, CCONCRETE};
- List<Hierarchy> totest = new ArrayList<>();
- for (int i1 = 0; i1 < iKinds.length; ++i1) {
- for (int i2 = 0; i2 < iKinds.length; ++i2) {
- for (int i3 = 0; i3 < iKinds.length; ++i3) {
- for (int c1 = 0; c1 < cKinds.length; ++c1) {
- for (int c2 = 0; c2 < cKinds.length; ++c2) {
- for (int c3 = 0; c3 < cKinds.length; ++c3) {
- totest.add( new Hierarchy(
- new ClassCase(cKinds[c1],
- new ClassCase(cKinds[c2],
- new ClassCase(cKinds[c3],
- null,
- iList(iKinds[i1])
- ),
- iList(iKinds[i2])
- ),
- iList(iKinds[i3])
- )));
- }
- }
- }
- }
- }
- }
- return totest;
- }
-
- private List<ClassCase> iList(Kind kind) {
- if (kind == null) {
- return Collections.EMPTY_LIST;
- } else {
- List<ClassCase> itfs = new ArrayList<>();
- itfs.add(new ClassCase(kind, null, Collections.EMPTY_LIST));
- return itfs;
- }
- }
-
- public List<Hierarchy> ciShapes() {
- return wrapInHierarchy(TTShape.allCases(true));
- }
-
- public List<Hierarchy> iShapes() {
- return wrapInClassAndHierarchy(TTShape.allCases(false));
- }
-
- public List<Hierarchy> wrapInClassAndHierarchy(List<ClassCase> ihs) {
- List<Hierarchy> totest = new ArrayList<>();
- for (ClassCase cc : ihs) {
- List<ClassCase> interfaces = new ArrayList<>();
- interfaces.add(cc);
- totest.add(new Hierarchy(new ClassCase(CNONE, null, interfaces)));
- }
- return totest;
- }
-
- public List<Hierarchy> wrapInHierarchy(List<ClassCase> ihs) {
- List<Hierarchy> totest = new ArrayList<>();
- for (ClassCase cc : ihs) {
- totest.add(new Hierarchy(cc));
- }
- return totest;
- }
-}
--- a/langtools/test/tools/javac/defaultMethods/fd/shapegen/Rule.java Tue Nov 20 15:43:28 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +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;
-
-/**
- *
- * @author Robert Field
- */
-public abstract class Rule {
-
- public final String name;
-
- public Rule(String name) {
- this.name = name;
- }
-
- abstract boolean guard(ClassCase cc);
-
- abstract void eval(ClassCase cc);
-
- @Override
- public String toString() {
- return name;
- }
-}
--- a/langtools/test/tools/javac/defaultMethods/fd/shapegen/RuleGroup.java Tue Nov 20 15:43:28 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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);
- }
- },
-
- });
-
-}
--- a/langtools/test/tools/javac/defaultMethods/fd/shapegen/TTNode.java Tue Nov 20 15:43:28 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +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 shapegen.ClassCase.Kind;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import static shapegen.ClassCase.Kind.*;
-
-/**
- * Type Template Node
- *
- * @author Robert Field
- */
-public class TTNode {
-
- final List<TTNode> supertypes;
- final boolean canBeClass;
-
- private int currentKindIndex;
- private Kind[] kinds;
-
- public TTNode(List<TTNode> subtypes, boolean canBeClass) {
- this.supertypes = subtypes;
- this.canBeClass = canBeClass;
- }
-
- public void start(boolean includeClasses) {
- kinds =
- supertypes.isEmpty()?
- (new Kind[]{IDEFAULT, IPRESENT})
- : ((includeClasses && canBeClass)?
- new Kind[]{CNONE, IVAC, IDEFAULT, IPRESENT}
- : new Kind[]{IVAC, IDEFAULT, IPRESENT});
- currentKindIndex = 0;
-
- for (TTNode sub : supertypes) {
- sub.start(includeClasses);
- }
- }
-
- public boolean next() {
- ++currentKindIndex;
- if (currentKindIndex >= kinds.length) {
- currentKindIndex = 0;
- return false;
- } else {
- return true;
- }
- }
-
- public void collectAllSubtypes(Set<TTNode> subs) {
- subs.add(this);
- for (TTNode n : supertypes) {
- n.collectAllSubtypes(subs);
- }
- }
-
- private Kind getKind() {
- return kinds[currentKindIndex];
- }
-
- boolean isInterface() {
- return getKind().isInterface;
- }
-
- boolean isClass() {
- return !isInterface();
- }
-
- boolean hasDefault() {
- return getKind() == IDEFAULT;
- }
-
- public boolean isValid() {
- for (TTNode n : supertypes) {
- if (!n.isValid() || (isInterface() && n.isClass())) {
- return false;
- }
- }
- return true;
- }
-
- public ClassCase genCase() {
- ClassCase subclass;
- List<TTNode> ttintfs;
- if (isClass() && !supertypes.isEmpty() && supertypes.get(0).isClass()) {
- subclass = supertypes.get(0).genCase();
- ttintfs = supertypes.subList(1, supertypes.size());
- } else {
- subclass = null;
- ttintfs = supertypes;
- }
- List<ClassCase> intfs = new ArrayList<>();
- for (TTNode node : ttintfs) {
- intfs.add(node.genCase());
- }
- return new ClassCase(getKind(), subclass, intfs);
- }
-}
--- a/langtools/test/tools/javac/defaultMethods/fd/shapegen/TTParser.java Tue Nov 20 15:43:28 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +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.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.io.IOException;
-import java.io.StringReader;
-
-import static java.lang.Character.isLetter;
-import static java.lang.Character.isUpperCase;
-import static java.lang.Character.isWhitespace;
-
-/**
- * Parse a type template definition string
- *
- * input :: classDef
- * classDef :: letter [ ( classDef* ) ]
- *
- * @author Robert Field
- */
-public class TTParser extends StringReader {
-
- private Map<Character, TTNode> letterMap = new HashMap<>();
- private char ch;
-
- private final String def;
-
- public TTParser(String s) {
- super(s);
- this.def = s;
- }
-
- private void advance() throws IOException {
- do {
- ch = (char)read();
- } while (isWhitespace(ch));
- }
-
- public TTNode parse() {
- try {
- advance();
- return classDef();
- } catch (IOException t) {
- throw new RuntimeException(t);
- }
- }
-
- private TTNode classDef() throws IOException {
- if (!isLetter(ch)) {
- if (ch == (char)-1) {
- throw new IOException("Unexpected end of type template in " + def);
- } else {
- throw new IOException("Unexpected character in type template: " + (Character)ch + " in " + def);
- }
- }
- char nodeCh = ch;
- TTNode node = letterMap.get(nodeCh);
- boolean canBeClass = isUpperCase(nodeCh);
- advance();
- if (node == null) {
- List<TTNode> subtypes = new ArrayList<>();
- if (ch == '(') {
- advance();
- while (ch != ')') {
- subtypes.add(classDef());
- }
- advance();
- }
- node = new TTNode(subtypes, canBeClass);
- letterMap.put(nodeCh, node);
- }
- return node;
- }
-}
--- a/langtools/test/tools/javac/defaultMethods/fd/shapegen/TTShape.java Tue Nov 20 15:43:28 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +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.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- *
- * @author Robert Field
- */
-public class TTShape {
-
- private final TTNode root;
- private final TTNode[] nodes;
-
- TTShape(TTNode root) {
- this.root = root;
- Set<TTNode> subs = new HashSet<>();
- root.collectAllSubtypes(subs);
- nodes = subs.toArray(new TTNode[subs.size()]);
- }
-
- private List<ClassCase> toCases(boolean includeClasses) {
- List<ClassCase> ccs = new ArrayList<>();
- root.start(includeClasses);
- int i;
- outer:
- while (true) {
- if (root.isValid()) {
- ClassCase cc = root.genCase();
- //System.out.println(cc);
- ccs.add(cc);
- }
-
- i = 0;
- do {
- if (i >= nodes.length) {
- break outer;
- }
- } while(!nodes[i++].next());
- }
- return ccs;
- }
-
- public static List<ClassCase> allCases(boolean includeClasses) {
- List<ClassCase> ccs = new ArrayList<>();
- for (TTShape shape : SHAPES) {
- ccs.addAll(shape.toCases(includeClasses));
- }
- return ccs;
- }
-
- public static TTShape parse(String s) {
- return new TTShape(new TTParser(s).parse());
- }
-
- public static final TTShape[] SHAPES = new TTShape[] {
- parse("a"),
- parse("a(b)"),
- parse("A(bb)"),
- parse("A(B(d)c(d))"),
- parse("A(b(c))"),
- parse("A(B(cd)d)"),
- parse("A(B(c)c)"),
- parse("A(B(Ce)d(e))"),
- parse("A(B(C)d(e))"),
- parse("A(Bc(d))"),
- parse("A(B(d)dc)"),
- parse("A(B(dc)dc)"),
- parse("A(B(c(d))d)"),
- parse("A(B(C(d))d)"),
- parse("A(B(C(e)d(e))e)"),
- parse("A(B(c(d))c)"),
- parse("A(B(dc(d))c)"),
- parse("A(B(C(d))d)"),
- };
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/InInterface.java Tue Nov 20 09:58:55 2012 -0800
@@ -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");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/InnerConstructor.java Tue Nov 20 09:58:55 2012 -0800
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/LambdaTranslationTest1.java Tue Nov 20 09:58:55 2012 -0800
@@ -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);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/LambdaTranslationTest2.java Tue Nov 20 09:58:55 2012 -0800
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/TBlock.java Tue Nov 20 09:58:55 2012 -0800
@@ -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); };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/TMapper.java Tue Nov 20 09:58:55 2012 -0800
@@ -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);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/TPredicate.java Tue Nov 20 09:58:55 2012 -0800
@@ -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);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestFDCCE.java Tue Nov 20 09:58:55 2012 -0800
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestInnerDefault.java Tue Nov 20 09:58:55 2012 -0800
@@ -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:*");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestInnerInstance.java Tue Nov 20 09:58:55 2012 -0800
@@ -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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestInnerVarArgsThis.java Tue Nov 20 09:58:55 2012 -0800
@@ -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();
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestInstance.java Tue Nov 20 09:58:55 2012 -0800
@@ -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");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestKinds.java Tue Nov 20 09:58:55 2012 -0800
@@ -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);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestNew.java Tue Nov 20 09:58:55 2012 -0800
@@ -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)");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestNewInner.java Tue Nov 20 09:58:55 2012 -0800
@@ -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)");
+ }
+ ***/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestSueCase1.java Tue Nov 20 09:58:55 2012 -0800
@@ -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");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestSueCase2.java Tue Nov 20 09:58:55 2012 -0800
@@ -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");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestSueCase4.java Tue Nov 20 09:58:55 2012 -0800
@@ -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");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestSuper.java Tue Nov 20 09:58:55 2012 -0800
@@ -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:*");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestSuperDefault.java Tue Nov 20 09:58:55 2012 -0800
@@ -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:*");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestTypeConversion.java Tue Nov 20 09:58:55 2012 -0800
@@ -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('@'), '@');
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestVarArgs.java Tue Nov 20 09:58:55 2012 -0800
@@ -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*");
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestVarArgsExt.java Tue Nov 20 09:58:55 2012 -0800
@@ -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();
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestVarArgsSuper.java Tue Nov 20 09:58:55 2012 -0800
@@ -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*");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestVarArgsSuperDefault.java Tue Nov 20 09:58:55 2012 -0800
@@ -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*");
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestVarArgsThis.java Tue Nov 20 09:58:55 2012 -0800
@@ -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*");
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/TEST.properties Tue Nov 20 09:58:55 2012 -0800
@@ -0,0 +1,2 @@
+TestNG.dirs = tools/javac/lambdaShapes
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/javac/FDTest.java Tue Nov 20 09:58:55 2012 -0800
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ *
+ * 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.javac;
+
+import org.openjdk.tests.shapegen.*;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.util.Pair;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.*;
+
+public class FDTest {
+
+ public enum TestKind {
+ POSITIVE,
+ NEGATIVE;
+
+ Collection<Hierarchy> getHierarchy(HierarchyGenerator hg) {
+ return this == POSITIVE ?
+ hg.getOK() : hg.getErr();
+ }
+ }
+
+ public static JavaCompiler comp;
+ public static StandardJavaFileManager fm;
+
+ @BeforeSuite
+ static void init() {
+ // create default shared JavaCompiler - reused across multiple
+ // compilations
+
+ comp = ToolProvider.getSystemJavaCompiler();
+ fm = comp.getStandardFileManager(null, null, null);
+ }
+
+ public static void main(String[] args) throws Exception {
+ init();
+
+ for (Pair<TestKind,Hierarchy> fdtest : generateCases()) {
+ runTest(fdtest.fst, fdtest.snd, comp, fm);
+ }
+ }
+
+ @Test(dataProvider = "fdCases")
+ public void testOneCase(TestKind tk, Hierarchy hs)
+ throws Exception {
+ FDTest.runTest(tk, hs, comp, fm);
+ }
+
+ @DataProvider(name = "fdCases")
+ public Object[][] caseGenerator() {
+ List<Pair<TestKind, Hierarchy>> cases = generateCases();
+ Object[][] fdCases = new Object[cases.size()][];
+ for (int i = 0; i < cases.size(); ++i) {
+ fdCases[i] = new Object[2];
+ fdCases[i][0] = cases.get(i).fst;
+ fdCases[i][1] = cases.get(i).snd;
+ }
+ return fdCases;
+ }
+
+ public static List<Pair<TestKind, Hierarchy>> generateCases() {
+ ArrayList<Pair<TestKind,Hierarchy>> list = new ArrayList<>();
+ HierarchyGenerator hg = new HierarchyGenerator();
+ for (TestKind tk : TestKind.values()) {
+ for (Hierarchy hs : tk.getHierarchy(hg)) {
+ list.add(new Pair<>(tk, hs));
+ }
+ }
+ return list;
+ }
+
+ public static void runTest(TestKind tk, Hierarchy hs,
+ JavaCompiler comp, StandardJavaFileManager fm) throws Exception {
+ new FDTest(tk, hs).run(comp, fm);
+ }
+
+ TestKind tk;
+ Hierarchy hs;
+ DefenderTestSource source;
+ DiagnosticChecker diagChecker;
+
+ public FDTest() {}
+
+ FDTest(TestKind tk, Hierarchy hs) {
+ this.tk = tk;
+ this.hs = hs;
+ this.source = new DefenderTestSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+
+ void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+ JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+ null, null, Arrays.asList(source));
+ try {
+ ct.analyze();
+ } catch (Throwable ex) {
+ fail("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ boolean errorExpected = tk == TestKind.NEGATIVE;
+ if (errorExpected != diagChecker.errorFound) {
+ fail("problem in source: \n" +
+ "\nerror found = " + diagChecker.errorFound +
+ "\nerror expected = " + errorExpected +
+ "\n" + dumpHierarchy() +
+ "\n" + source.getCharContent(true));
+ }
+ }
+
+ String dumpHierarchy() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("root = " + hs.root + "\n");
+ for (ClassCase cc : hs.all) {
+ buf.append(" class name = " + cc.getName() + "\n");
+ buf.append(" class OK = " + cc.get_OK() + "\n");
+ buf.append(" prov = " + cc.get_mprov() + "\n");
+
+ }
+ return buf.toString();
+ }
+
+ class DefenderTestSource extends SimpleJavaFileObject {
+
+ String source;
+
+ public DefenderTestSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ StringBuilder buf = new StringBuilder();
+ List<ClassCase> defaultRef = new ArrayList<>();
+ for (ClassCase cc : hs.all) {
+ Hierarchy.genClassDef(buf, cc, null, defaultRef);
+ }
+ source = buf.toString();
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/AttributeInjector.java Tue Nov 20 09:58:55 2012 -0800
@@ -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);
+ }
+*/
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/ClassFile.java Tue Nov 20 09:58:55 2012 -0800
@@ -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);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/ClassFilePreprocessor.java Tue Nov 20 09:58:55 2012 -0800
@@ -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);
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/ClassToInterfaceConverter.java Tue Nov 20 09:58:55 2012 -0800
@@ -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);
+ }
+*/
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/Compiler.java Tue Nov 20 09:58:55 2012 -0800
@@ -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());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/DirectedClassLoader.java Tue Nov 20 09:58:55 2012 -0800
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java Tue Nov 20 09:58:55 2012 -0800
@@ -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();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/TestHarness.java Tue Nov 20 09:58:55 2012 -0800
@@ -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();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/ClassCase.java Tue Nov 20 09:58:55 2012 -0800
@@ -0,0 +1,312 @@
+/*
+ * 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.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class ClassCase {
+
+ public enum Kind {
+ IVAC (true, "v"),
+ IPRESENT (true, "p"),
+ IDEFAULT (true, "d"),
+ CNONE (false, "n"),
+ CABSTRACT (false, "a"),
+ CCONCRETE (false, "c");
+
+ private final String prefix;
+ public final boolean isInterface;
+
+ Kind(boolean isInterface, String prefix) {
+ this.isInterface = isInterface;
+ this.prefix = prefix;
+ }
+
+ public String getPrefix() { return prefix; }
+ }
+
+ public final Kind kind;
+ private final ClassCase superclass;
+ private final List<ClassCase> supertypes;
+
+ private String name;
+ private boolean _OK;
+ private boolean _HasClassMethod;
+ private Set<ClassCase> _mprov;
+ private boolean _IsConcrete;
+ private boolean _HasDefault;
+ private ClassCase _mres;
+ private ClassCase _mdefend;
+
+ private Set<RuleGroup> executed = new HashSet<RuleGroup>();
+
+ public ClassCase(Kind kind, ClassCase superclass, List<ClassCase> interfaces) {
+ this.kind = kind;
+ this.superclass = superclass;
+
+ // Set supertypes from superclass (if any) and interfaces
+ List<ClassCase> lc;
+ if (superclass == null) {
+ lc = interfaces;
+ } else {
+ lc = new ArrayList<>();
+ lc.add(superclass);
+ lc.addAll(interfaces);
+ }
+ this.supertypes = lc;
+ }
+
+ public final boolean isInterface() { return kind.isInterface; }
+ public final boolean isClass() { return !kind.isInterface; }
+
+ public Set<ClassCase> get_mprov() {
+ exec(RuleGroup.PROVENENCE);
+ return _mprov;
+ }
+
+ public void set_mprov(ClassCase cc) {
+ Set<ClassCase> s = new HashSet<>();
+ s.add(cc);
+ _mprov = s;
+ }
+
+ public void set_mprov(Set<ClassCase> s) {
+ _mprov = s;
+ }
+
+ public ClassCase get_mres() {
+ exec(RuleGroup.RESOLUTION);
+ return _mres;
+ }
+
+ public void set_mres(ClassCase cc) {
+ _mres = cc;
+ }
+
+ public ClassCase get_mdefend() {
+ exec(RuleGroup.DEFENDER);
+ return _mdefend;
+ }
+
+ public void set_mdefend(ClassCase cc) {
+ _mdefend = cc;
+ }
+
+ public boolean get_HasClassMethod() {
+ exec(RuleGroup.PROVENENCE);
+ return _HasClassMethod;
+ }
+
+ public void set_HasClassMethod(boolean bool) {
+ _HasClassMethod = bool;
+ }
+
+ public boolean get_HasDefault() {
+ exec(RuleGroup.MARKER);
+ return _HasDefault;
+ }
+
+ public void set_HasDefault(boolean bool) {
+ _HasDefault = bool;
+ }
+
+ public boolean get_IsConcrete() {
+ exec(RuleGroup.MARKER);
+ return _IsConcrete;
+ }
+
+ public void set_IsConcrete(boolean bool) {
+ _IsConcrete = bool;
+ }
+
+ public boolean get_OK() {
+ exec(RuleGroup.CHECKING);
+ return _OK;
+ }
+
+ public void set_OK(boolean bool) {
+ _OK = bool;
+ }
+
+ public boolean isMethodDefined() {
+ for (ClassCase cc : supertypes) {
+ if (cc.isMethodDefined()) {
+ return true;
+ }
+ }
+ switch (kind) {
+ case CCONCRETE:
+ case CABSTRACT:
+ case IPRESENT:
+ case IDEFAULT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isAbstract() {
+ return isMethodDefined() && (get_mres()==null);
+ }
+
+ public boolean hasSuperclass() {
+ return superclass != null;
+ }
+
+ public ClassCase getSuperclass() {
+ return superclass;
+ }
+
+ public List<ClassCase> getSupertypes() {
+ return supertypes;
+ }
+
+ public List<ClassCase> getInterfaces() {
+ if (superclass != null) {
+ if (supertypes.get(0) != superclass) {
+ throw new AssertionError("superclass missing from supertypes");
+ }
+ return supertypes.subList(1, supertypes.size());
+ } else {
+ return supertypes;
+ }
+ }
+
+ public boolean isSubtypeOf(ClassCase cc) {
+ // S-Refl
+ if (cc.equals(this)) {
+ return true;
+ }
+
+ // S-Def
+ for (ClassCase sp : getSupertypes()) {
+ if (cc.equals(sp)) {
+ return true;
+ }
+ }
+
+ // _S-Trans
+ for (ClassCase sp : getSupertypes()) {
+ if (sp.isSubtypeOf(cc)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void init(Map<String, Integer> namingContext) {
+ if (name != null) {
+ return; // Already inited
+ }
+
+ for (ClassCase sup : supertypes) {
+ sup.init(namingContext);
+ }
+
+ // Build name
+ StringBuilder sb = new StringBuilder();
+ if (!supertypes.isEmpty()) {
+ sb.append(isInterface() ? "I" : "C");
+ for (ClassCase cc : supertypes) {
+ sb.append(cc.getName());
+ }
+ sb.append(kind.isInterface ? "i" : "c");
+ }
+ sb.append(kind.prefix);
+ String pname = sb.toString();
+ Integer icnt = namingContext.get(pname);
+ int cnt = icnt == null ? 0 : icnt;
+ ++cnt;
+ namingContext.put(pname, cnt);
+ if (cnt > 1) {
+ sb.append(cnt);
+ }
+ this.name = sb.toString();
+ }
+
+ public boolean isa(Kind... kinds) {
+ for (Kind k : kinds) {
+ if (kind == k) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void exec(RuleGroup rg ) {
+ if (!executed.contains(rg)) {
+ rg.exec(this);
+ executed.add(rg);
+ }
+ }
+
+ public void collectClasses(Set<ClassCase> seen) {
+ seen.add(this);
+ for (ClassCase cc : supertypes) {
+ cc.collectClasses(seen);
+ }
+ }
+
+ public String getID() {
+ if (name == null) {
+ throw new Error("Access to uninitialized ClassCase");
+ } else {
+ return name;
+ }
+ }
+
+ public final String getName() {
+ if (name == null) {
+ return "ClassCase uninited@" + hashCode();
+ } else {
+ return name;
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof ClassCase && getID().equals(((ClassCase)obj).getID());
+ }
+
+ @Override
+ public int hashCode() {
+ return getID().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/Hierarchy.java Tue Nov 20 09:58:55 2012 -0800
@@ -0,0 +1,209 @@
+/*
+ * 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.ArrayList;
+import java.util.List;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class Hierarchy {
+
+ public final ClassCase root;
+ public final Set<ClassCase> all;
+
+ public Hierarchy(ClassCase root) {
+ this.root = root;
+ root.init(new HashMap<String,Integer>());
+ Set<ClassCase> allClasses = new HashSet<>();
+ root.collectClasses(allClasses);
+ this.all = allClasses;
+ }
+
+ public boolean anyDefaults() {
+ for (ClassCase cc : all) {
+ if (cc.kind == IDEFAULT) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean get_OK() {
+ return root.get_OK();
+ }
+
+ public String testName() {
+ return root + "Test";
+ }
+
+ private static void genInterfaceList(StringBuilder buf, String prefix, List<ClassCase> interfaces) {
+ if (!interfaces.isEmpty()) {
+ buf.append(" ");
+ buf.append(prefix);
+ buf.append(" ");
+ buf.append(interfaces.get(0));
+ for (int i = 1; i < interfaces.size(); ++i) {
+ buf.append(", " + interfaces.get(i));
+ }
+ }
+ }
+
+ public static void genClassDef(StringBuilder buf, ClassCase cc, String implClass, List<ClassCase> defaultRef) {
+ if (cc.isInterface()) {
+ buf.append("interface ");
+ buf.append(cc.getName() + " ");
+ genInterfaceList(buf, "extends", cc.getInterfaces());
+ buf.append(" {\n");
+
+ switch (cc.kind) {
+ case IDEFAULT:
+ buf.append(" default String m() { return \"\"; }\n");
+ defaultRef.add(cc);
+ break;
+ case IPRESENT:
+ buf.append(" String m();\n");
+ break;
+ case IVAC:
+ break;
+ default:
+ throw new AssertionError("Unexpected kind");
+ }
+ buf.append("}\n\n");
+ } else {
+ buf.append((cc.isAbstract()? "abstract " : ""));
+ buf.append(" class " + cc.getName());
+ if (cc.getSuperclass() != null) {
+ buf.append(" extends " + cc.getSuperclass());
+ }
+
+ genInterfaceList(buf, "implements", cc.getInterfaces());
+ buf.append(" {\n");
+
+ switch (cc.kind) {
+ case CCONCRETE:
+ buf.append(" public String m() { return \"\"; }\n");
+ break;
+ case CABSTRACT:
+ buf.append(" public abstract String m();\n");
+ break;
+ case CNONE:
+ break;
+ default:
+ throw new AssertionError("Unexpected kind");
+ }
+ buf.append("}\n\n");
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof Hierarchy && root.getID().equals(((Hierarchy)obj).root.getID());
+ }
+
+ @Override
+ public int hashCode() {
+ return root.getID().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ 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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/HierarchyGenerator.java Tue Nov 20 09:58:55 2012 -0800
@@ -0,0 +1,192 @@
+/*
+ * 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 org.openjdk.tests.shapegen.ClassCase.Kind;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
+
+import static java.lang.Math.pow;
+
+/**
+ *
+ * @author Robert Field
+ */
+public final class HierarchyGenerator {
+
+ private int okcnt = 0;
+ private int errcnt = 0;
+ private Set<Hierarchy> uniqueOK = new HashSet<>();
+ private Set<Hierarchy> uniqueErr = new HashSet<>();
+
+ /**
+ * @param args the command line arguments
+ */
+ public HierarchyGenerator() {
+ organize("exhaustive interface", iExhaustive(2));
+ organize("exhaustive class", cExhaustive());
+ organize("shapes interface", iShapes());
+ organize("shapes class/interface", ciShapes());
+
+ System.out.printf("\nExpect OK: %d -- unique %d", okcnt, uniqueOK.size());
+ System.out.printf("\nExpect Error: %d -- unique %d\n", errcnt, uniqueErr.size());
+ }
+
+ public Collection<Hierarchy> getOK() {
+ return uniqueOK;
+ }
+
+ public Collection<Hierarchy> getErr() {
+ return uniqueErr;
+ }
+
+ private void organize(String tname, List<Hierarchy> totest) {
+ System.out.printf("\nGenerating %s....\n", tname);
+ int nodefault = 0;
+ List<Hierarchy> ok = new ArrayList<>();
+ List<Hierarchy> err = new ArrayList<>();
+ for (Hierarchy cc : totest) {
+ if (cc.anyDefaults()) {
+ //System.out.printf(" %s\n", cc);
+ if (cc.get_OK()) {
+ ok.add(cc);
+ } else {
+ err.add(cc);
+ }
+ } else {
+ ++nodefault;
+ }
+ }
+
+ errcnt += err.size();
+ okcnt += ok.size();
+ uniqueErr.addAll(err);
+ uniqueOK.addAll(ok);
+
+ System.out.printf(" %5d No default\n %5d Error\n %5d OK\n %5d Total\n",
+ nodefault, err.size(), ok.size(), totest.size());
+ }
+
+ public List<Hierarchy> iExhaustive(int idepth) {
+ List<ClassCase> current = new ArrayList<>();
+ for (int i = 0; i < idepth; ++i) {
+ current = ilayer(current);
+ }
+ return wrapInClassAndHierarchy(current);
+ }
+
+ private List<ClassCase> ilayer(List<ClassCase> srcLayer) {
+ List<ClassCase> lay = new ArrayList<>();
+ for (int i = (int) pow(2, srcLayer.size()) - 1; i >= 0; --i) {
+ List<ClassCase> itfs = new ArrayList<>();
+ for (int b = srcLayer.size() - 1; b >= 0; --b) {
+ if ((i & (1<<b)) != 0) {
+ itfs.add(srcLayer.get(b));
+ }
+ }
+ lay.add(new ClassCase(IVAC, null, itfs));
+ lay.add(new ClassCase(IPRESENT, null, itfs));
+ lay.add(new ClassCase(IDEFAULT, null, itfs));
+ lay.add(new ClassCase(IDEFAULT, null, itfs));
+ }
+ return lay;
+ }
+
+ public List<Hierarchy> cExhaustive() {
+ final Kind[] iKinds = new Kind[]{IDEFAULT, IVAC, IPRESENT, null};
+ final Kind[] cKinds = new Kind[]{CNONE, CABSTRACT, CCONCRETE};
+ List<Hierarchy> totest = new ArrayList<>();
+ for (int i1 = 0; i1 < iKinds.length; ++i1) {
+ for (int i2 = 0; i2 < iKinds.length; ++i2) {
+ for (int i3 = 0; i3 < iKinds.length; ++i3) {
+ for (int c1 = 0; c1 < cKinds.length; ++c1) {
+ for (int c2 = 0; c2 < cKinds.length; ++c2) {
+ for (int c3 = 0; c3 < cKinds.length; ++c3) {
+ totest.add( new Hierarchy(
+ new ClassCase(cKinds[c1],
+ new ClassCase(cKinds[c2],
+ new ClassCase(cKinds[c3],
+ null,
+ iList(iKinds[i1])
+ ),
+ iList(iKinds[i2])
+ ),
+ iList(iKinds[i3])
+ )));
+ }
+ }
+ }
+ }
+ }
+ }
+ return totest;
+ }
+
+ public static final List<ClassCase> EMPTY_LIST = new ArrayList<>();
+
+ private List<ClassCase> iList(Kind kind) {
+ if (kind == null) {
+ return EMPTY_LIST;
+ } else {
+ List<ClassCase> itfs = new ArrayList<>();
+ itfs.add(new ClassCase(kind, null, EMPTY_LIST));
+ return itfs;
+ }
+ }
+
+ public List<Hierarchy> ciShapes() {
+ return wrapInHierarchy(TTShape.allCases(true));
+ }
+
+ public List<Hierarchy> iShapes() {
+ return wrapInClassAndHierarchy(TTShape.allCases(false));
+ }
+
+ public List<Hierarchy> wrapInClassAndHierarchy(List<ClassCase> ihs) {
+ List<Hierarchy> totest = new ArrayList<>();
+ for (ClassCase cc : ihs) {
+ List<ClassCase> interfaces = new ArrayList<>();
+ interfaces.add(cc);
+ totest.add(new Hierarchy(new ClassCase(CNONE, null, interfaces)));
+ }
+ return totest;
+ }
+
+ public List<Hierarchy> wrapInHierarchy(List<ClassCase> ihs) {
+ List<Hierarchy> totest = new ArrayList<>();
+ for (ClassCase cc : ihs) {
+ totest.add(new Hierarchy(cc));
+ }
+ return totest;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/Rule.java Tue Nov 20 09:58:55 2012 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+/**
+ *
+ * @author Robert Field
+ */
+public abstract class Rule {
+
+ public final String name;
+
+ public Rule(String name) {
+ this.name = name;
+ }
+
+ abstract boolean guard(ClassCase cc);
+
+ abstract void eval(ClassCase cc);
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/RuleGroup.java Tue Nov 20 09:58:55 2012 -0800
@@ -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);
+ }
+ },
+
+ });
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/TTNode.java Tue Nov 20 09:58:55 2012 -0800
@@ -0,0 +1,126 @@
+/*
+ * 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 org.openjdk.tests.shapegen.ClassCase.Kind;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
+
+/**
+ * Type Template Node
+ *
+ * @author Robert Field
+ */
+public class TTNode {
+
+ final List<TTNode> supertypes;
+ final boolean canBeClass;
+
+ private int currentKindIndex;
+ private Kind[] kinds;
+
+ public TTNode(List<TTNode> subtypes, boolean canBeClass) {
+ this.supertypes = subtypes;
+ this.canBeClass = canBeClass;
+ }
+
+ public void start(boolean includeClasses) {
+ kinds =
+ supertypes.isEmpty()?
+ (new Kind[]{IDEFAULT, IPRESENT})
+ : ((includeClasses && canBeClass)?
+ new Kind[]{CNONE, IVAC, IDEFAULT, IPRESENT}
+ : new Kind[]{IVAC, IDEFAULT, IPRESENT});
+ currentKindIndex = 0;
+
+ for (TTNode sub : supertypes) {
+ sub.start(includeClasses);
+ }
+ }
+
+ public boolean next() {
+ ++currentKindIndex;
+ if (currentKindIndex >= kinds.length) {
+ currentKindIndex = 0;
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public void collectAllSubtypes(Set<TTNode> subs) {
+ subs.add(this);
+ for (TTNode n : supertypes) {
+ n.collectAllSubtypes(subs);
+ }
+ }
+
+ private Kind getKind() {
+ return kinds[currentKindIndex];
+ }
+
+ boolean isInterface() {
+ return getKind().isInterface;
+ }
+
+ boolean isClass() {
+ return !isInterface();
+ }
+
+ boolean hasDefault() {
+ return getKind() == IDEFAULT;
+ }
+
+ public boolean isValid() {
+ for (TTNode n : supertypes) {
+ if (!n.isValid() || (isInterface() && n.isClass())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public ClassCase genCase() {
+ ClassCase subclass;
+ List<TTNode> ttintfs;
+ if (isClass() && !supertypes.isEmpty() && supertypes.get(0).isClass()) {
+ subclass = supertypes.get(0).genCase();
+ ttintfs = supertypes.subList(1, supertypes.size());
+ } else {
+ subclass = null;
+ ttintfs = supertypes;
+ }
+ List<ClassCase> intfs = new ArrayList<>();
+ for (TTNode node : ttintfs) {
+ intfs.add(node.genCase());
+ }
+ return new ClassCase(getKind(), subclass, intfs);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/TTParser.java Tue Nov 20 09:58:55 2012 -0800
@@ -0,0 +1,100 @@
+/*
+ * 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.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.StringReader;
+
+import static java.lang.Character.isLetter;
+import static java.lang.Character.isUpperCase;
+import static java.lang.Character.isWhitespace;
+
+/**
+ * Parse a type template definition string
+ *
+ * input :: classDef
+ * classDef :: letter [ ( classDef* ) ]
+ *
+ * @author Robert Field
+ */
+public class TTParser extends StringReader {
+
+ private Map<Character, TTNode> letterMap = new HashMap<>();
+ private char ch;
+
+ private final String def;
+
+ public TTParser(String s) {
+ super(s);
+ this.def = s;
+ }
+
+ private void advance() throws IOException {
+ do {
+ ch = (char)read();
+ } while (isWhitespace(ch));
+ }
+
+ public TTNode parse() {
+ try {
+ advance();
+ return classDef();
+ } catch (IOException t) {
+ throw new RuntimeException(t);
+ }
+ }
+
+ private TTNode classDef() throws IOException {
+ if (!isLetter(ch)) {
+ if (ch == (char)-1) {
+ throw new IOException("Unexpected end of type template in " + def);
+ } else {
+ throw new IOException("Unexpected character in type template: " + (Character)ch + " in " + def);
+ }
+ }
+ char nodeCh = ch;
+ TTNode node = letterMap.get(nodeCh);
+ boolean canBeClass = isUpperCase(nodeCh);
+ advance();
+ if (node == null) {
+ List<TTNode> subtypes = new ArrayList<>();
+ if (ch == '(') {
+ advance();
+ while (ch != ')') {
+ subtypes.add(classDef());
+ }
+ advance();
+ }
+ node = new TTNode(subtypes, canBeClass);
+ letterMap.put(nodeCh, node);
+ }
+ return node;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/TTShape.java Tue Nov 20 09:58:55 2012 -0800
@@ -0,0 +1,104 @@
+/*
+ * 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.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class TTShape {
+
+ private final TTNode root;
+ private final TTNode[] nodes;
+
+ TTShape(TTNode root) {
+ this.root = root;
+ Set<TTNode> subs = new HashSet<>();
+ root.collectAllSubtypes(subs);
+ nodes = subs.toArray(new TTNode[subs.size()]);
+ }
+
+ private List<ClassCase> toCases(boolean includeClasses) {
+ List<ClassCase> ccs = new ArrayList<>();
+ root.start(includeClasses);
+ int i;
+ outer:
+ while (true) {
+ if (root.isValid()) {
+ ClassCase cc = root.genCase();
+ //System.out.println(cc);
+ ccs.add(cc);
+ }
+
+ i = 0;
+ do {
+ if (i >= nodes.length) {
+ break outer;
+ }
+ } while(!nodes[i++].next());
+ }
+ return ccs;
+ }
+
+ public static List<ClassCase> allCases(boolean includeClasses) {
+ List<ClassCase> ccs = new ArrayList<>();
+ for (TTShape shape : SHAPES) {
+ ccs.addAll(shape.toCases(includeClasses));
+ }
+ return ccs;
+ }
+
+ public static TTShape parse(String s) {
+ return new TTShape(new TTParser(s).parse());
+ }
+
+ public static final TTShape[] SHAPES = new TTShape[] {
+ parse("a"),
+ parse("a(b)"),
+ parse("A(bb)"),
+ parse("A(B(d)c(d))"),
+ parse("A(b(c))"),
+ parse("A(B(cd)d)"),
+ parse("A(B(c)c)"),
+ parse("A(B(Ce)d(e))"),
+ parse("A(B(C)d(e))"),
+ parse("A(Bc(d))"),
+ parse("A(B(d)dc)"),
+ parse("A(B(dc)dc)"),
+ parse("A(B(c(d))d)"),
+ parse("A(B(C(d))d)"),
+ parse("A(B(C(e)d(e))e)"),
+ parse("A(B(c(d))c)"),
+ parse("A(B(dc(d))c)"),
+ parse("A(B(C(d))d)"),
+ };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java Tue Nov 20 09:58:55 2012 -0800
@@ -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() {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/FDSeparateCompilationTest.java Tue Nov 20 09:58:55 2012 -0800
@@ -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;
+ }
+ }
+}