8004102: Add support for generic functional descriptors
authormcimadamore
Fri, 30 Nov 2012 15:14:25 +0000
changeset 14723 46aa71a5e4e0
parent 14722 aaa39655aa2e
child 14724 b542db73539a
8004102: Add support for generic functional descriptors Summary: Method references are allowed to have a generic functional interface descriptor target Reviewed-by: jjg
langtools/src/share/classes/com/sun/tools/javac/code/Types.java
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
langtools/test/tools/javac/diags/examples/InvalidGenericDescInFunctionalInterface.java
langtools/test/tools/javac/diags/examples/InvalidGenericLambdaTarget.java
langtools/test/tools/javac/lambda/FunctionalInterfaceConversionTest.java
langtools/test/tools/javac/lambda/LambdaConversionTest.java
langtools/test/tools/javac/lambda/MethodReference57.java
langtools/test/tools/javac/lambda/MethodReference58.java
langtools/test/tools/javac/lambda/MethodReference58.out
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Nov 30 15:14:12 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Nov 30 15:14:25 2012 +0000
@@ -437,23 +437,8 @@
                 throw failure("not.a.functional.intf.1",
                             diags.fragment("no.abstracts", Kinds.kindName(origin), origin));
             } else if (abstracts.size() == 1) {
-                if (abstracts.first().type.tag == FORALL) {
-                    throw failure("invalid.generic.desc.in.functional.intf",
-                            abstracts.first(),
-                            Kinds.kindName(origin),
-                            origin);
-                } else {
-                    return new FunctionDescriptor(abstracts.first());
-                }
+                return new FunctionDescriptor(abstracts.first());
             } else { // size > 1
-                for (Symbol msym : abstracts) {
-                    if (msym.type.tag == FORALL) {
-                        throw failure("invalid.generic.desc.in.functional.intf",
-                                abstracts.first(),
-                                Kinds.kindName(origin),
-                                origin);
-                    }
-                }
                 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList());
                 if (descRes == null) {
                     //we can get here if the functional interface is ill-formed
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Nov 30 15:14:12 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Nov 30 15:14:25 2012 +0000
@@ -2204,6 +2204,14 @@
                 lambdaType = fallbackDescriptorType(that);
             }
 
+            if (lambdaType.hasTag(FORALL)) {
+                //lambda expression target desc cannot be a generic method
+                resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
+                        lambdaType, kindName(target.tsym), target.tsym));
+                result = that.type = types.createErrorType(pt());
+                return;
+            }
+
             if (!TreeInfo.isExplicitLambda(that)) {
                 //add param type info in the AST
                 List<Type> actuals = lambdaType.getParameterTypes();
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Nov 30 15:14:12 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Nov 30 15:14:25 2012 +0000
@@ -187,8 +187,9 @@
     {0}
 
 # 0: symbol, 1: symbol kind, 2: symbol
-compiler.misc.invalid.generic.desc.in.functional.intf=\
-    invalid functional descriptor: method {0} in {1} {2} is generic
+compiler.misc.invalid.generic.lambda.target=\
+    invalid functional descriptor for lambda expression\n\
+    method {0} in {1} {2} is generic
 
 # 0: symbol kind, 1: symbol
 compiler.misc.incompatible.descs.in.functional.intf=\
--- a/langtools/test/tools/javac/diags/examples/InvalidGenericDescInFunctionalInterface.java	Fri Nov 30 15:14:12 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +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.
- */
-
-// key: compiler.err.prob.found.req
-// key: compiler.misc.invalid.generic.desc.in.functional.intf
-
-class InvalidGenericDescInFunctionalIntf {
-
-    interface SAM {
-        <Z> void m();
-    }
-
-    SAM s = x-> { };
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/InvalidGenericLambdaTarget.java	Fri Nov 30 15:14:25 2012 +0000
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.prob.found.req
+// key: compiler.misc.invalid.generic.lambda.target
+
+class InvalidGenericLambdaTarget {
+
+    interface SAM {
+        <Z> void m();
+    }
+
+    SAM s = x-> { };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceConversionTest.java	Fri Nov 30 15:14:25 2012 +0000
@@ -0,0 +1,280 @@
+/*
+ * 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
+ * @bug 8003280 8004102
+ * @summary Add lambda tests
+ *  perform several automated checks in lambda conversion, esp. around accessibility
+ * @author  Maurizio Cimadamore
+ * @run main FunctionalInterfaceConversionTest
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+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 FunctionalInterfaceConversionTest {
+
+    enum PackageKind {
+        NO_PKG(""),
+        PKG_A("a");
+
+        String pkg;
+
+        PackageKind(String pkg) {
+            this.pkg = pkg;
+        }
+
+        String getPkgDecl() {
+            return this == NO_PKG ?
+                "" :
+                "package " + pkg + ";";
+        }
+
+        String getImportStat() {
+            return this == NO_PKG ?
+                "" :
+                "import " + pkg + ".*;";
+        }
+    }
+
+    enum SamKind {
+        CLASS("public class Sam {  }"),
+        ABSTACT_CLASS("public abstract class Sam {  }"),
+        ANNOTATION("public @interface Sam {  }"),
+        ENUM("public enum Sam { }"),
+        INTERFACE("public interface Sam { \n #METH; \n }");
+
+        String sam_str;
+
+        SamKind(String sam_str) {
+            this.sam_str = sam_str;
+        }
+
+        String getSam(String methStr) {
+            return sam_str.replaceAll("#METH", methStr);
+        }
+    }
+
+    enum ModifierKind {
+        PUBLIC("public"),
+        PACKAGE("");
+
+        String modifier_str;
+
+        ModifierKind(String modifier_str) {
+            this.modifier_str = modifier_str;
+        }
+
+        boolean stricterThan(ModifierKind that) {
+            return this.ordinal() > that.ordinal();
+        }
+    }
+
+    enum TypeKind {
+        EXCEPTION("Exception"),
+        PKG_CLASS("PackageClass");
+
+        String typeStr;
+
+        private TypeKind(String typeStr) {
+            this.typeStr = typeStr;
+        }
+    }
+
+    enum ExprKind {
+        LAMBDA("x -> null"),
+        MREF("this::m");
+
+        String exprStr;
+
+        private ExprKind(String exprStr) {
+            this.exprStr = exprStr;
+        }
+    }
+
+    enum MethodKind {
+        NONE(""),
+        NON_GENERIC("public abstract #R m(#ARG s) throws #T;"),
+        GENERIC("public abstract <X> #R m(#ARG s) throws #T;");
+
+        String methodTemplate;
+
+        private MethodKind(String methodTemplate) {
+            this.methodTemplate = methodTemplate;
+        }
+
+        String getMethod(TypeKind retType, TypeKind argType, TypeKind thrownType) {
+            return methodTemplate.replaceAll("#R", retType.typeStr).
+                    replaceAll("#ARG", argType.typeStr).
+                    replaceAll("#T", thrownType.typeStr);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+        for (PackageKind samPkg : PackageKind.values()) {
+            for (ModifierKind modKind : ModifierKind.values()) {
+                for (SamKind samKind : SamKind.values()) {
+                    for (MethodKind samMeth : MethodKind.values()) {
+                        for (MethodKind clientMeth : MethodKind.values()) {
+                            for (TypeKind retType : TypeKind.values()) {
+                                for (TypeKind argType : TypeKind.values()) {
+                                    for (TypeKind thrownType : TypeKind.values()) {
+                                        for (ExprKind exprKind : ExprKind.values()) {
+                                            new FunctionalInterfaceConversionTest(samPkg, modKind, samKind,
+                                                    samMeth, clientMeth, retType, argType, thrownType, exprKind).test(comp, fm);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    PackageKind samPkg;
+    ModifierKind modKind;
+    SamKind samKind;
+    MethodKind samMeth;
+    MethodKind clientMeth;
+    TypeKind retType;
+    TypeKind argType;
+    TypeKind thrownType;
+    ExprKind exprKind;
+    DiagnosticChecker dc;
+
+    SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
+        public String toString() {
+            return template.replaceAll("#P", samPkg.getPkgDecl()).
+                    replaceAll("#C", samKind.getSam(samMeth.getMethod(retType, argType, thrownType)));
+        }
+    };
+
+    SourceFile pkgClassSourceFile = new SourceFile("PackageClass.java",
+                                                   "#P\n #M class PackageClass extends Exception { }") {
+        public String toString() {
+            return template.replaceAll("#P", samPkg.getPkgDecl()).
+                    replaceAll("#M", modKind.modifier_str);
+        }
+    };
+
+    SourceFile clientSourceFile = new SourceFile("Client.java",
+                                                 "#I\n abstract class Client { \n" +
+                                                 "  Sam s = #E;\n" +
+                                                 "  #M \n }") {
+        public String toString() {
+            return template.replaceAll("#I", samPkg.getImportStat())
+                    .replaceAll("#E", exprKind.exprStr)
+                    .replaceAll("#M", clientMeth.getMethod(retType, argType, thrownType));
+        }
+    };
+
+    FunctionalInterfaceConversionTest(PackageKind samPkg, ModifierKind modKind, SamKind samKind,
+            MethodKind samMeth, MethodKind clientMeth, TypeKind retType, TypeKind argType,
+            TypeKind thrownType, ExprKind exprKind) {
+        this.samPkg = samPkg;
+        this.modKind = modKind;
+        this.samKind = samKind;
+        this.samMeth = samMeth;
+        this.clientMeth = clientMeth;
+        this.retType = retType;
+        this.argType = argType;
+        this.thrownType = thrownType;
+        this.exprKind = exprKind;
+        this.dc = new DiagnosticChecker();
+    }
+
+    void test(JavaCompiler comp, StandardJavaFileManager fm) throws Exception {
+        JavacTask ct = (JavacTask)comp.getTask(null, fm, dc,
+                null, null, Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
+        ct.analyze();
+        if (dc.errorFound == checkSamConversion()) {
+            throw new AssertionError(samSourceFile + "\n\n" + pkgClassSourceFile + "\n\n" + clientSourceFile);
+        }
+    }
+
+    boolean checkSamConversion() {
+        if (samKind != SamKind.INTERFACE) {
+            //sam type must be an interface
+            return false;
+        } else if (samMeth == MethodKind.NONE) {
+            //interface must have at least a method
+            return false;
+        } else if (exprKind == ExprKind.LAMBDA &&
+                samMeth != MethodKind.NON_GENERIC) {
+            //target method for lambda must be non-generic
+            return false;
+        } else if (exprKind == ExprKind.MREF &&
+                clientMeth == MethodKind.NONE) {
+            return false;
+        } else if (samPkg != PackageKind.NO_PKG &&
+                modKind != ModifierKind.PUBLIC &&
+                (retType == TypeKind.PKG_CLASS ||
+                argType == TypeKind.PKG_CLASS ||
+                thrownType == TypeKind.PKG_CLASS)) {
+            //target must not contain inaccessible types
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    abstract class SourceFile extends SimpleJavaFileObject {
+
+        protected String template;
+
+        public SourceFile(String filename, String template) {
+            super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
+            this.template = template;
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return toString();
+        }
+
+        public abstract String toString();
+    }
+
+    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+        boolean errorFound = false;
+
+        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+                errorFound = true;
+            }
+        }
+    }
+}
--- a/langtools/test/tools/javac/lambda/LambdaConversionTest.java	Fri Nov 30 15:14:12 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,246 +0,0 @@
-/*
- * Copyright (c) 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.
- *
- * 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 8003280
- * @summary Add lambda tests
- *  perform several automated checks in lambda conversion, esp. around accessibility
- * @author  Maurizio Cimadamore
- * @run main LambdaConversionTest
- */
-
-import com.sun.source.util.JavacTask;
-import java.net.URI;
-import java.util.Arrays;
-import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.ToolProvider;
-
-public class LambdaConversionTest {
-
-    enum PackageKind {
-        NO_PKG(""),
-        PKG_A("a");
-
-        String pkg;
-
-        PackageKind(String pkg) {
-            this.pkg = pkg;
-        }
-
-        String getPkgDecl() {
-            return this == NO_PKG ?
-                "" :
-                "package " + pkg + ";";
-        }
-
-        String getImportStat() {
-            return this == NO_PKG ?
-                "" :
-                "import " + pkg + ".*;";
-        }
-    }
-
-    enum SamKind {
-        CLASS("public class Sam {  }"),
-        ABSTACT_CLASS("public abstract class Sam {  }"),
-        ANNOTATION("public @interface Sam {  }"),
-        ENUM("public enum Sam { }"),
-        INTERFACE("public interface Sam { \n #METH; \n }");
-
-        String sam_str;
-
-        SamKind(String sam_str) {
-            this.sam_str = sam_str;
-        }
-
-        String getSam(String methStr) {
-            return sam_str.replaceAll("#METH", methStr);
-        }
-    }
-
-    enum ModifierKind {
-        PUBLIC("public"),
-        PACKAGE("");
-
-        String modifier_str;
-
-        ModifierKind(String modifier_str) {
-            this.modifier_str = modifier_str;
-        }
-
-        boolean stricterThan(ModifierKind that) {
-            return this.ordinal() > that.ordinal();
-        }
-    }
-
-    enum TypeKind {
-        EXCEPTION("Exception"),
-        PKG_CLASS("PackageClass");
-
-        String typeStr;
-
-        private TypeKind(String typeStr) {
-            this.typeStr = typeStr;
-        }
-    }
-
-    enum MethodKind {
-        NONE(""),
-        NON_GENERIC("public #R m(#ARG s) throws #T;"),
-        GENERIC("public <X> #R m(#ARG s) throws #T;");
-
-        String methodTemplate;
-
-        private MethodKind(String methodTemplate) {
-            this.methodTemplate = methodTemplate;
-        }
-
-        String getMethod(TypeKind retType, TypeKind argType, TypeKind thrownType) {
-            return methodTemplate.replaceAll("#R", retType.typeStr).
-                    replaceAll("#ARG", argType.typeStr).
-                    replaceAll("#T", thrownType.typeStr);
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        for (PackageKind samPkg : PackageKind.values()) {
-            for (ModifierKind modKind : ModifierKind.values()) {
-                for (SamKind samKind : SamKind.values()) {
-                    for (MethodKind meth : MethodKind.values()) {
-                        for (TypeKind retType : TypeKind.values()) {
-                            for (TypeKind argType : TypeKind.values()) {
-                                for (TypeKind thrownType : TypeKind.values()) {
-                                    new LambdaConversionTest(samPkg, modKind, samKind,
-                                            meth, retType, argType, thrownType).test();
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    PackageKind samPkg;
-    ModifierKind modKind;
-    SamKind samKind;
-    MethodKind meth;
-    TypeKind retType;
-    TypeKind argType;
-    TypeKind thrownType;
-
-    SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
-        public String toString() {
-            return template.replaceAll("#P", samPkg.getPkgDecl()).
-                    replaceAll("#C", samKind.getSam(meth.getMethod(retType, argType, thrownType)));
-        }
-    };
-
-    SourceFile pkgClassSourceFile = new SourceFile("PackageClass.java",
-                                                   "#P\n #M class PackageClass extends Exception { }") {
-        public String toString() {
-            return template.replaceAll("#P", samPkg.getPkgDecl()).
-                    replaceAll("#M", modKind.modifier_str);
-        }
-    };
-
-    SourceFile clientSourceFile = new SourceFile("Client.java",
-                                                 "#I\n class Client { Sam s = x -> null; }") {
-        public String toString() {
-            return template.replaceAll("#I", samPkg.getImportStat());
-        }
-    };
-
-    LambdaConversionTest(PackageKind samPkg, ModifierKind modKind, SamKind samKind,
-            MethodKind meth, TypeKind retType, TypeKind argType, TypeKind thrownType) {
-        this.samPkg = samPkg;
-        this.modKind = modKind;
-        this.samKind = samKind;
-        this.meth = meth;
-        this.retType = retType;
-        this.argType = argType;
-        this.thrownType = thrownType;
-    }
-
-    void test() throws Exception {
-        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
-        DiagnosticChecker dc = new DiagnosticChecker();
-        JavacTask ct = (JavacTask)tool.getTask(null, null, dc,
-                null, null, Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
-        ct.analyze();
-        if (dc.errorFound == checkSamConversion()) {
-            throw new AssertionError(samSourceFile + "\n\n" + pkgClassSourceFile + "\n\n" + clientSourceFile);
-        }
-    }
-
-    boolean checkSamConversion() {
-        if (samKind != SamKind.INTERFACE) {
-            //sam type must be an interface
-            return false;
-        } else if (meth != MethodKind.NON_GENERIC) {
-            //target method must be non-generic
-            return false;
-        } else if (samPkg != PackageKind.NO_PKG &&
-                modKind != ModifierKind.PUBLIC &&
-                (retType == TypeKind.PKG_CLASS ||
-                argType == TypeKind.PKG_CLASS ||
-                thrownType == TypeKind.PKG_CLASS)) {
-            //target must not contain inaccessible types
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    abstract class SourceFile extends SimpleJavaFileObject {
-
-        protected String template;
-
-        public SourceFile(String filename, String template) {
-            super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
-            this.template = template;
-        }
-
-        @Override
-        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
-            return toString();
-        }
-
-        public abstract String toString();
-    }
-
-    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
-
-        boolean errorFound = false;
-
-        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/lambda/MethodReference57.java	Fri Nov 30 15:14:25 2012 +0000
@@ -0,0 +1,41 @@
+/*
+ * 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
+ * @bug 8004102
+ * @summary Add support for generic functional descriptors
+ * @compile MethodReference57.java
+ */
+class MethodReference57 {
+
+    interface F {
+        <X> void m();
+    }
+
+    void test() {
+        F f = this::g; //ok
+    }
+
+    void g() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference58.java	Fri Nov 30 15:14:25 2012 +0000
@@ -0,0 +1,46 @@
+/*
+ * 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
+ * @bug 8004102
+ * @summary Add support for generic functional descriptors
+ * @compile/fail/ref=MethodReference58.out -XDrawDiagnostics MethodReference58.java
+ */
+class MethodReference58 {
+
+    interface F_Object {
+        <X> void m(X x);
+    }
+
+    interface F_Integer {
+        <X extends Integer> void m(X x);
+    }
+
+    void test() {
+        F_Object f1 = this::g; //incompatible bounds
+        F_Integer f2 = this::g; //ok
+    }
+
+    <Z extends Number> void g(Z z) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference58.out	Fri Nov 30 15:14:25 2012 +0000
@@ -0,0 +1,2 @@
+MethodReference58.java:41:23: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, g, Z, X, kindname.class, MethodReference58, (compiler.misc.inferred.do.not.conform.to.upper.bounds: X, java.lang.Number)))
+1 error