changeset 2596:62a67e0875ff

8024930: Re-enable disabled bridging tests Reviewed-by: psandoz, rfield
author briangoetz
date Wed, 30 Oct 2013 14:12:16 -0400
parents 537fa895fd74
children 6b4d6205366c
files test/tools/javac/lambdaShapes/org/openjdk/tests/separate/Compiler.java test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java test/tools/javac/lambdaShapes/org/openjdk/tests/separate/TestHarness.java test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java
diffstat 4 files changed, 110 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/Compiler.java	Wed Oct 30 18:09:49 2013 +0000
+++ b/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/Compiler.java	Wed Oct 30 14:12:16 2013 -0400
@@ -46,7 +46,7 @@
         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";
@@ -85,7 +85,7 @@
     }
 
     public void setFlags(Flags ... flags) {
-        this.flags = new HashSet<Flags>(Arrays.asList(flags));
+        this.flags = new HashSet<>(Arrays.asList(flags));
     }
 
     public void addPostprocessor(ClassFilePreprocessor cfp) {
@@ -131,17 +131,10 @@
         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());
-            }
-        }
+        if (superClass != null)
+            outputDirs.putAll(compileHierarchy(superClass));
+        for (Extends ext : type.getSupertypes())
+            outputDirs.putAll(compileHierarchy(ext.getType()));
 
         return outputDirs;
     }
@@ -157,8 +150,12 @@
         SourceProcessor accum =
             (name, src) -> { files.add(new SourceFile(name, src)); };
 
-        for (Type dep : type.typeDependencies()) {
-            dep.generateAsDependency(accum, type.methodDependencies());
+        Collection<Type> deps = type.typeDependencies(type.isFullCompilation());
+        for (Type dep : deps) {
+            if (type.isFullCompilation())
+                dep.generate(accum);
+            else
+                dep.generateAsDependency(accum, type.methodDependencies());
         }
 
         type.generate(accum);
@@ -185,7 +182,7 @@
                 StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
         } catch (IOException e) {
             throw new RuntimeException(
-                "IOException encountered during compilation");
+                "IOException encountered during compilation", e);
         }
         Boolean result = ct.call();
         if (result == Boolean.FALSE) {
--- a/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java	Wed Oct 30 18:09:49 2013 +0000
+++ b/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java	Wed Oct 30 14:12:16 2013 -0400
@@ -48,7 +48,7 @@
             generate(pw);
             return sw.toString();
         }
-    };
+    }
 
     public static class AccessFlag extends Element {
         private String flag;
@@ -125,6 +125,7 @@
         // (and thus will be present in stubs)
         private Set<Method> methodDependencies;
         private List<Type> typeDependencies;
+        private boolean fullCompilation;
 
         protected Type(String name,
                 List<AccessFlag> flags, List<TypeParameter> params,
@@ -214,6 +215,14 @@
             methodDependencies.add(m);
         }
 
+        public boolean isFullCompilation() {
+            return fullCompilation;
+        }
+
+        public void setFullCompilation(boolean fullCompilation) {
+            this.fullCompilation = fullCompilation;
+        }
+
         // Convenience method for creating an Extends object using this
         // class and specified type arguments.
         public Extends with(String ... args) {
@@ -255,14 +264,23 @@
             pw.println("}");
         }
 
-        public Collection<Type> typeDependencies() {
+        public Collection<Type> typeDependencies(boolean recursive) {
             HashMap<String,Type> dependencies = new HashMap<>();
             Type superclass = getSuperclass();
             if (superclass != null) {
                 dependencies.put(superclass.getName(), superclass);
+                if (recursive) {
+                    for (Type t : superclass.typeDependencies(true))
+                        dependencies.put(t.getName(), t);
+                }
             }
-            for (Extends e : getSupertypes())
+            for (Extends e : getSupertypes()) {
                 dependencies.put(e.getType().getName(), e.getType());
+                if (recursive) {
+                    for (Type t : e.getType().typeDependencies(true))
+                        dependencies.put(t.getName(), t);
+                }
+            }
             // Do these last so that they override
             for (Type t : this.typeDependencies)
                 dependencies.put(t.getName(), t);
--- a/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/TestHarness.java	Wed Oct 30 18:09:49 2013 +0000
+++ b/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/TestHarness.java	Wed Oct 30 14:12:16 2013 -0400
@@ -198,7 +198,7 @@
                 assertEquals(res, value);
             }
         } catch (InvocationTargetException | IllegalAccessException e) {
-            fail("Unexpected exception thrown: " + e.getCause());
+            fail("Unexpected exception thrown: " + e.getCause(), e.getCause());
         }
     }
 
@@ -227,8 +227,7 @@
      * a return type of 'int', and no arguments.
      */
     public void assertInvokeVirtualEquals(int value, Class target) {
-        assertInvokeVirtualEquals(
-            new Integer(value), target, stdCM, "-1");
+        assertInvokeVirtualEquals(value, target, stdCM, "-1");
     }
 
     /**
@@ -260,12 +259,31 @@
         Compiler compiler = compilerLocal.get();
         compiler.setFlags(compilerFlags());
 
-        assertInvokeInterfaceEquals(
-            new Integer(value), target, new Extends(iface), stdAM);
+        assertInvokeInterfaceEquals(value, target, new Extends(iface), stdAM);
 
         compiler.cleanup();
     }
 
+    protected void assertInvokeInterfaceThrows(java.lang.Class<? extends Throwable> errorClass,
+                                               Class target, Extends iface, AbstractMethod method,
+                                               String... args) {
+        try {
+            assertInvokeInterfaceEquals(0, target, iface, method, args);
+            fail("Expected exception: " + errorClass);
+        }
+        catch (AssertionError e) {
+            Throwable cause = e.getCause();
+            if (cause == null)
+                throw e;
+            else if ((errorClass.isAssignableFrom(cause.getClass()))) {
+                // this is success
+                return;
+            }
+            else
+                throw e;
+        }
+    }
+
     /**
      * Creates a class which calls target::method(args) via invokevirtual,
      * compiles and loads both the new class and 'target', and then invokes
--- a/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java	Wed Oct 30 18:09:49 2013 +0000
+++ b/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java	Wed Oct 30 14:12:16 2013 -0400
@@ -25,18 +25,22 @@
 
 package org.openjdk.tests.vm;
 
-import java.lang.reflect.*;
-import java.util.*;
-import java.io.File;
-import java.io.IOException;
+import org.openjdk.tests.separate.Compiler;
+import org.openjdk.tests.separate.TestHarness;
+import org.testng.annotations.Test;
 
-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.AbstractMethod;
+import static org.openjdk.tests.separate.SourceModel.AccessFlag;
 import static org.openjdk.tests.separate.SourceModel.Class;
+import static org.openjdk.tests.separate.SourceModel.ConcreteMethod;
+import static org.openjdk.tests.separate.SourceModel.DefaultMethod;
+import static org.openjdk.tests.separate.SourceModel.Extends;
+import static org.openjdk.tests.separate.SourceModel.Interface;
+import static org.openjdk.tests.separate.SourceModel.MethodParameter;
+import static org.openjdk.tests.separate.SourceModel.TypeParameter;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.fail;
 
 @Test(groups = "vm")
 public class DefaultMethodsTest extends TestHarness {
@@ -186,7 +190,7 @@
      * TEST: D d = new D(); d.m() == 22;
      * TEST: I i = new D(); i.m() == 22;
      */
-    void testExistingInheritedOverride() {
+    public 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"));
@@ -258,7 +262,6 @@
      * TEST: C c = new C(); c.m() throws ICCE
      */
     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);
@@ -390,19 +393,16 @@
 
     /**
      * interface I<T> { default int m(T t) { return 99; } }
-     * Class C implements I<String> { public int m() { return 88; } }
+     * Class C implements I<String> { public int m(String s) { return 88; } }
      *
-     * TEST: C c = new C(); c.m() == 88;
-     * TEST: I i = new C(); i.m() == 88;
+     * TEST: C c = new C(); c.m("string") == 88;
+     * TEST: I i = new C(); i.m("string") == 88;
      */
-    @Test(enabled=false)
     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(
@@ -415,9 +415,11 @@
         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\"");
+        assertInvokeVirtualEquals(88, C, cm, "-1", "\"string\"");
+        assertInvokeInterfaceEquals(99, C, I.with("String"), pm, "\"string\"");
+
+        C.setFullCompilation(true); // Force full bridge generation
+        assertInvokeInterfaceEquals(88, C, I.with("String"), pm, "\"string\"");
     }
 
     /**
@@ -485,7 +487,6 @@
      * 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;
      */
-    @Test(enabled=false)
     public void testBridges() {
         DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;",
             new MethodParameter("T", "t"), new MethodParameter("V", "v"),
@@ -518,13 +519,17 @@
             J.with("String", "T"), pm2);
         Class C = new Class("C", K.with("String"), cm);
 
+        // First, without compiler bridges
         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);
+        assertInvokeInterfaceEquals(99, C, I.with("String", "String", "String"), pm0, args);
+        assertInvokeInterfaceThrows(AbstractMethodError.class, C, J.with("String", "String"), pm1, args);
+        assertInvokeInterfaceThrows(AbstractMethodError.class, C, K.with("String"), pm2, args);
+
+        // Then with compiler bridges
+        C.setFullCompilation(true);
+        assertInvokeInterfaceEquals(88, C, I.with("String", "String", "String"), pm0, args);
+        assertInvokeInterfaceEquals(88, C, J.with("String", "String"), pm1, args);
+        assertInvokeInterfaceEquals(88, C, K.with("String"), pm2, args);
     }
 
     /**
@@ -536,8 +541,6 @@
      * 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();"));
@@ -559,8 +562,6 @@
      * TODO: add case for K k = new C(); k.m() throws ICCE
      */
     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);
@@ -635,8 +636,7 @@
         AbstractMethod pm = new AbstractMethod("int", stdMethodName,
             new MethodParameter("String", "s"));
 
-        assertInvokeInterfaceEquals(
-            new Integer(88), C, new Extends(I), pm, "\"\"");
+        assertInvokeInterfaceEquals(88, C, new Extends(I), pm, "\"\"");
     }
 
     /**
@@ -674,7 +674,6 @@
      * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger;
      * TEST: S s = new S(); s.foo() == new Integer(99)
      */
-    @Test(enabled=false)
     public void testCovarBridge() {
         Interface I = new Interface("I", new DefaultMethod(
             "Integer", "m", "return new Integer(88);"));
@@ -692,7 +691,8 @@
         S.addCompilationDependency(Dstub);
         S.addCompilationDependency(DstubMethod);
 
-        assertInvokeVirtualEquals(new Integer(99), S, toCall, "null");
+        // NEGATIVE test for separate compilation -- dispatches to I, not C
+        assertInvokeVirtualEquals(88, S, toCall, "null");
     }
 
     /**
@@ -719,7 +719,7 @@
         S.addCompilationDependency(Dstub);
         S.addCompilationDependency(DstubMethod);
 
-        assertInvokeVirtualEquals(new Integer(88), S, toCall, "null");
+        assertInvokeVirtualEquals(88, S, toCall, "null");
     }
 
     /**
@@ -757,7 +757,6 @@
      * Test that a erased-signature-matching method does not implement
      * non-language-level matching methods
      */
-    @Test(enabled=false)
     public void testNonConcreteFill() {
         AbstractMethod ipm = new AbstractMethod("int", "m",
             new MethodParameter("T", "t"),
@@ -781,13 +780,14 @@
             new MethodParameter("T", "t"),
             new MethodParameter("String", "s"),
             new MethodParameter("String", "w"));
+        DefaultMethod kdm = new DefaultMethod("int", "m", "return 99;",
+                                              new MethodParameter("T", "t"),
+                                              new MethodParameter("String", "v"),
+                                              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")));
+            kdm);
 
         Class C = new Class("C",
             K.with("String"),
@@ -797,13 +797,18 @@
                 new MethodParameter("Object", "v"),
                 new MethodParameter("String", "w")));
 
+        // First, without compiler bridges
         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);
+        assertInvokeInterfaceEquals(99, C, K.with("String"), kpm, a, a, a);
+        assertInvokeInterfaceEquals(77, C, J.with("String", "String"), jpm, a, a, a);
+        assertInvokeInterfaceThrows(AbstractMethodError.class, C, I.with("String", "String", "String"), ipm, a, a, a);
+
+        // Now, with bridges
+        J.setFullCompilation(true);
+        K.setFullCompilation(true);
+        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() {