8004102: Add support for generic functional descriptors

Fri, 30 Nov 2012 15:14:25 +0000

author
mcimadamore
date
Fri, 30 Nov 2012 15:14:25 +0000
changeset 1434
34d1ebaf4645
parent 1433
4f9853659bf1
child 1435
9b26c96f5138

8004102: Add support for generic functional descriptors
Summary: Method references are allowed to have a generic functional interface descriptor target
Reviewed-by: jjg

src/share/classes/com/sun/tools/javac/code/Types.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Attr.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/resources/compiler.properties file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/InvalidGenericDescInFunctionalInterface.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/InvalidGenericLambdaTarget.java file | annotate | diff | comparison | revisions
test/tools/javac/lambda/FunctionalInterfaceConversionTest.java file | annotate | diff | comparison | revisions
test/tools/javac/lambda/LambdaConversionTest.java file | annotate | diff | comparison | revisions
test/tools/javac/lambda/MethodReference57.java file | annotate | diff | comparison | revisions
test/tools/javac/lambda/MethodReference58.java file | annotate | diff | comparison | revisions
test/tools/javac/lambda/MethodReference58.out file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Nov 30 15:14:12 2012 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Nov 30 15:14:25 2012 +0000
     1.3 @@ -437,23 +437,8 @@
     1.4                  throw failure("not.a.functional.intf.1",
     1.5                              diags.fragment("no.abstracts", Kinds.kindName(origin), origin));
     1.6              } else if (abstracts.size() == 1) {
     1.7 -                if (abstracts.first().type.tag == FORALL) {
     1.8 -                    throw failure("invalid.generic.desc.in.functional.intf",
     1.9 -                            abstracts.first(),
    1.10 -                            Kinds.kindName(origin),
    1.11 -                            origin);
    1.12 -                } else {
    1.13 -                    return new FunctionDescriptor(abstracts.first());
    1.14 -                }
    1.15 +                return new FunctionDescriptor(abstracts.first());
    1.16              } else { // size > 1
    1.17 -                for (Symbol msym : abstracts) {
    1.18 -                    if (msym.type.tag == FORALL) {
    1.19 -                        throw failure("invalid.generic.desc.in.functional.intf",
    1.20 -                                abstracts.first(),
    1.21 -                                Kinds.kindName(origin),
    1.22 -                                origin);
    1.23 -                    }
    1.24 -                }
    1.25                  FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList());
    1.26                  if (descRes == null) {
    1.27                      //we can get here if the functional interface is ill-formed
     2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Nov 30 15:14:12 2012 +0000
     2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Nov 30 15:14:25 2012 +0000
     2.3 @@ -2204,6 +2204,14 @@
     2.4                  lambdaType = fallbackDescriptorType(that);
     2.5              }
     2.6  
     2.7 +            if (lambdaType.hasTag(FORALL)) {
     2.8 +                //lambda expression target desc cannot be a generic method
     2.9 +                resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
    2.10 +                        lambdaType, kindName(target.tsym), target.tsym));
    2.11 +                result = that.type = types.createErrorType(pt());
    2.12 +                return;
    2.13 +            }
    2.14 +
    2.15              if (!TreeInfo.isExplicitLambda(that)) {
    2.16                  //add param type info in the AST
    2.17                  List<Type> actuals = lambdaType.getParameterTypes();
     3.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Nov 30 15:14:12 2012 +0000
     3.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Nov 30 15:14:25 2012 +0000
     3.3 @@ -187,8 +187,9 @@
     3.4      {0}
     3.5  
     3.6  # 0: symbol, 1: symbol kind, 2: symbol
     3.7 -compiler.misc.invalid.generic.desc.in.functional.intf=\
     3.8 -    invalid functional descriptor: method {0} in {1} {2} is generic
     3.9 +compiler.misc.invalid.generic.lambda.target=\
    3.10 +    invalid functional descriptor for lambda expression\n\
    3.11 +    method {0} in {1} {2} is generic
    3.12  
    3.13  # 0: symbol kind, 1: symbol
    3.14  compiler.misc.incompatible.descs.in.functional.intf=\
     4.1 --- a/test/tools/javac/diags/examples/InvalidGenericDescInFunctionalInterface.java	Fri Nov 30 15:14:12 2012 +0000
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,34 +0,0 @@
     4.4 -/*
     4.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     4.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 - *
     4.8 - * This code is free software; you can redistribute it and/or modify it
     4.9 - * under the terms of the GNU General Public License version 2 only, as
    4.10 - * published by the Free Software Foundation.
    4.11 - *
    4.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
    4.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.15 - * version 2 for more details (a copy is included in the LICENSE file that
    4.16 - * accompanied this code).
    4.17 - *
    4.18 - * You should have received a copy of the GNU General Public License version
    4.19 - * 2 along with this work; if not, write to the Free Software Foundation,
    4.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.21 - *
    4.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.23 - * or visit www.oracle.com if you need additional information or have any
    4.24 - * questions.
    4.25 - */
    4.26 -
    4.27 -// key: compiler.err.prob.found.req
    4.28 -// key: compiler.misc.invalid.generic.desc.in.functional.intf
    4.29 -
    4.30 -class InvalidGenericDescInFunctionalIntf {
    4.31 -
    4.32 -    interface SAM {
    4.33 -        <Z> void m();
    4.34 -    }
    4.35 -
    4.36 -    SAM s = x-> { };
    4.37 -}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/tools/javac/diags/examples/InvalidGenericLambdaTarget.java	Fri Nov 30 15:14:25 2012 +0000
     5.3 @@ -0,0 +1,34 @@
     5.4 +/*
     5.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.
    5.11 + *
    5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.15 + * version 2 for more details (a copy is included in the LICENSE file that
    5.16 + * accompanied this code).
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License version
    5.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.21 + *
    5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.23 + * or visit www.oracle.com if you need additional information or have any
    5.24 + * questions.
    5.25 + */
    5.26 +
    5.27 +// key: compiler.err.prob.found.req
    5.28 +// key: compiler.misc.invalid.generic.lambda.target
    5.29 +
    5.30 +class InvalidGenericLambdaTarget {
    5.31 +
    5.32 +    interface SAM {
    5.33 +        <Z> void m();
    5.34 +    }
    5.35 +
    5.36 +    SAM s = x-> { };
    5.37 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/test/tools/javac/lambda/FunctionalInterfaceConversionTest.java	Fri Nov 30 15:14:25 2012 +0000
     6.3 @@ -0,0 +1,280 @@
     6.4 +/*
     6.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.
    6.11 + *
    6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.15 + * version 2 for more details (a copy is included in the LICENSE file that
    6.16 + * accompanied this code).
    6.17 + *
    6.18 + * You should have received a copy of the GNU General Public License version
    6.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.21 + *
    6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.23 + * or visit www.oracle.com if you need additional information or have any
    6.24 + * questions.
    6.25 + */
    6.26 +
    6.27 +/**
    6.28 + * @test
    6.29 + * @bug 8003280 8004102
    6.30 + * @summary Add lambda tests
    6.31 + *  perform several automated checks in lambda conversion, esp. around accessibility
    6.32 + * @author  Maurizio Cimadamore
    6.33 + * @run main FunctionalInterfaceConversionTest
    6.34 + */
    6.35 +
    6.36 +import com.sun.source.util.JavacTask;
    6.37 +import java.net.URI;
    6.38 +import java.util.Arrays;
    6.39 +import javax.tools.Diagnostic;
    6.40 +import javax.tools.JavaCompiler;
    6.41 +import javax.tools.JavaFileObject;
    6.42 +import javax.tools.SimpleJavaFileObject;
    6.43 +import javax.tools.StandardJavaFileManager;
    6.44 +import javax.tools.ToolProvider;
    6.45 +
    6.46 +public class FunctionalInterfaceConversionTest {
    6.47 +
    6.48 +    enum PackageKind {
    6.49 +        NO_PKG(""),
    6.50 +        PKG_A("a");
    6.51 +
    6.52 +        String pkg;
    6.53 +
    6.54 +        PackageKind(String pkg) {
    6.55 +            this.pkg = pkg;
    6.56 +        }
    6.57 +
    6.58 +        String getPkgDecl() {
    6.59 +            return this == NO_PKG ?
    6.60 +                "" :
    6.61 +                "package " + pkg + ";";
    6.62 +        }
    6.63 +
    6.64 +        String getImportStat() {
    6.65 +            return this == NO_PKG ?
    6.66 +                "" :
    6.67 +                "import " + pkg + ".*;";
    6.68 +        }
    6.69 +    }
    6.70 +
    6.71 +    enum SamKind {
    6.72 +        CLASS("public class Sam {  }"),
    6.73 +        ABSTACT_CLASS("public abstract class Sam {  }"),
    6.74 +        ANNOTATION("public @interface Sam {  }"),
    6.75 +        ENUM("public enum Sam { }"),
    6.76 +        INTERFACE("public interface Sam { \n #METH; \n }");
    6.77 +
    6.78 +        String sam_str;
    6.79 +
    6.80 +        SamKind(String sam_str) {
    6.81 +            this.sam_str = sam_str;
    6.82 +        }
    6.83 +
    6.84 +        String getSam(String methStr) {
    6.85 +            return sam_str.replaceAll("#METH", methStr);
    6.86 +        }
    6.87 +    }
    6.88 +
    6.89 +    enum ModifierKind {
    6.90 +        PUBLIC("public"),
    6.91 +        PACKAGE("");
    6.92 +
    6.93 +        String modifier_str;
    6.94 +
    6.95 +        ModifierKind(String modifier_str) {
    6.96 +            this.modifier_str = modifier_str;
    6.97 +        }
    6.98 +
    6.99 +        boolean stricterThan(ModifierKind that) {
   6.100 +            return this.ordinal() > that.ordinal();
   6.101 +        }
   6.102 +    }
   6.103 +
   6.104 +    enum TypeKind {
   6.105 +        EXCEPTION("Exception"),
   6.106 +        PKG_CLASS("PackageClass");
   6.107 +
   6.108 +        String typeStr;
   6.109 +
   6.110 +        private TypeKind(String typeStr) {
   6.111 +            this.typeStr = typeStr;
   6.112 +        }
   6.113 +    }
   6.114 +
   6.115 +    enum ExprKind {
   6.116 +        LAMBDA("x -> null"),
   6.117 +        MREF("this::m");
   6.118 +
   6.119 +        String exprStr;
   6.120 +
   6.121 +        private ExprKind(String exprStr) {
   6.122 +            this.exprStr = exprStr;
   6.123 +        }
   6.124 +    }
   6.125 +
   6.126 +    enum MethodKind {
   6.127 +        NONE(""),
   6.128 +        NON_GENERIC("public abstract #R m(#ARG s) throws #T;"),
   6.129 +        GENERIC("public abstract <X> #R m(#ARG s) throws #T;");
   6.130 +
   6.131 +        String methodTemplate;
   6.132 +
   6.133 +        private MethodKind(String methodTemplate) {
   6.134 +            this.methodTemplate = methodTemplate;
   6.135 +        }
   6.136 +
   6.137 +        String getMethod(TypeKind retType, TypeKind argType, TypeKind thrownType) {
   6.138 +            return methodTemplate.replaceAll("#R", retType.typeStr).
   6.139 +                    replaceAll("#ARG", argType.typeStr).
   6.140 +                    replaceAll("#T", thrownType.typeStr);
   6.141 +        }
   6.142 +    }
   6.143 +
   6.144 +    public static void main(String[] args) throws Exception {
   6.145 +        final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
   6.146 +        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
   6.147 +        for (PackageKind samPkg : PackageKind.values()) {
   6.148 +            for (ModifierKind modKind : ModifierKind.values()) {
   6.149 +                for (SamKind samKind : SamKind.values()) {
   6.150 +                    for (MethodKind samMeth : MethodKind.values()) {
   6.151 +                        for (MethodKind clientMeth : MethodKind.values()) {
   6.152 +                            for (TypeKind retType : TypeKind.values()) {
   6.153 +                                for (TypeKind argType : TypeKind.values()) {
   6.154 +                                    for (TypeKind thrownType : TypeKind.values()) {
   6.155 +                                        for (ExprKind exprKind : ExprKind.values()) {
   6.156 +                                            new FunctionalInterfaceConversionTest(samPkg, modKind, samKind,
   6.157 +                                                    samMeth, clientMeth, retType, argType, thrownType, exprKind).test(comp, fm);
   6.158 +                                        }
   6.159 +                                    }
   6.160 +                                }
   6.161 +                            }
   6.162 +                        }
   6.163 +                    }
   6.164 +                }
   6.165 +            }
   6.166 +        }
   6.167 +    }
   6.168 +
   6.169 +    PackageKind samPkg;
   6.170 +    ModifierKind modKind;
   6.171 +    SamKind samKind;
   6.172 +    MethodKind samMeth;
   6.173 +    MethodKind clientMeth;
   6.174 +    TypeKind retType;
   6.175 +    TypeKind argType;
   6.176 +    TypeKind thrownType;
   6.177 +    ExprKind exprKind;
   6.178 +    DiagnosticChecker dc;
   6.179 +
   6.180 +    SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
   6.181 +        public String toString() {
   6.182 +            return template.replaceAll("#P", samPkg.getPkgDecl()).
   6.183 +                    replaceAll("#C", samKind.getSam(samMeth.getMethod(retType, argType, thrownType)));
   6.184 +        }
   6.185 +    };
   6.186 +
   6.187 +    SourceFile pkgClassSourceFile = new SourceFile("PackageClass.java",
   6.188 +                                                   "#P\n #M class PackageClass extends Exception { }") {
   6.189 +        public String toString() {
   6.190 +            return template.replaceAll("#P", samPkg.getPkgDecl()).
   6.191 +                    replaceAll("#M", modKind.modifier_str);
   6.192 +        }
   6.193 +    };
   6.194 +
   6.195 +    SourceFile clientSourceFile = new SourceFile("Client.java",
   6.196 +                                                 "#I\n abstract class Client { \n" +
   6.197 +                                                 "  Sam s = #E;\n" +
   6.198 +                                                 "  #M \n }") {
   6.199 +        public String toString() {
   6.200 +            return template.replaceAll("#I", samPkg.getImportStat())
   6.201 +                    .replaceAll("#E", exprKind.exprStr)
   6.202 +                    .replaceAll("#M", clientMeth.getMethod(retType, argType, thrownType));
   6.203 +        }
   6.204 +    };
   6.205 +
   6.206 +    FunctionalInterfaceConversionTest(PackageKind samPkg, ModifierKind modKind, SamKind samKind,
   6.207 +            MethodKind samMeth, MethodKind clientMeth, TypeKind retType, TypeKind argType,
   6.208 +            TypeKind thrownType, ExprKind exprKind) {
   6.209 +        this.samPkg = samPkg;
   6.210 +        this.modKind = modKind;
   6.211 +        this.samKind = samKind;
   6.212 +        this.samMeth = samMeth;
   6.213 +        this.clientMeth = clientMeth;
   6.214 +        this.retType = retType;
   6.215 +        this.argType = argType;
   6.216 +        this.thrownType = thrownType;
   6.217 +        this.exprKind = exprKind;
   6.218 +        this.dc = new DiagnosticChecker();
   6.219 +    }
   6.220 +
   6.221 +    void test(JavaCompiler comp, StandardJavaFileManager fm) throws Exception {
   6.222 +        JavacTask ct = (JavacTask)comp.getTask(null, fm, dc,
   6.223 +                null, null, Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
   6.224 +        ct.analyze();
   6.225 +        if (dc.errorFound == checkSamConversion()) {
   6.226 +            throw new AssertionError(samSourceFile + "\n\n" + pkgClassSourceFile + "\n\n" + clientSourceFile);
   6.227 +        }
   6.228 +    }
   6.229 +
   6.230 +    boolean checkSamConversion() {
   6.231 +        if (samKind != SamKind.INTERFACE) {
   6.232 +            //sam type must be an interface
   6.233 +            return false;
   6.234 +        } else if (samMeth == MethodKind.NONE) {
   6.235 +            //interface must have at least a method
   6.236 +            return false;
   6.237 +        } else if (exprKind == ExprKind.LAMBDA &&
   6.238 +                samMeth != MethodKind.NON_GENERIC) {
   6.239 +            //target method for lambda must be non-generic
   6.240 +            return false;
   6.241 +        } else if (exprKind == ExprKind.MREF &&
   6.242 +                clientMeth == MethodKind.NONE) {
   6.243 +            return false;
   6.244 +        } else if (samPkg != PackageKind.NO_PKG &&
   6.245 +                modKind != ModifierKind.PUBLIC &&
   6.246 +                (retType == TypeKind.PKG_CLASS ||
   6.247 +                argType == TypeKind.PKG_CLASS ||
   6.248 +                thrownType == TypeKind.PKG_CLASS)) {
   6.249 +            //target must not contain inaccessible types
   6.250 +            return false;
   6.251 +        } else {
   6.252 +            return true;
   6.253 +        }
   6.254 +    }
   6.255 +
   6.256 +    abstract class SourceFile extends SimpleJavaFileObject {
   6.257 +
   6.258 +        protected String template;
   6.259 +
   6.260 +        public SourceFile(String filename, String template) {
   6.261 +            super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
   6.262 +            this.template = template;
   6.263 +        }
   6.264 +
   6.265 +        @Override
   6.266 +        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   6.267 +            return toString();
   6.268 +        }
   6.269 +
   6.270 +        public abstract String toString();
   6.271 +    }
   6.272 +
   6.273 +    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   6.274 +
   6.275 +        boolean errorFound = false;
   6.276 +
   6.277 +        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   6.278 +            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
   6.279 +                errorFound = true;
   6.280 +            }
   6.281 +        }
   6.282 +    }
   6.283 +}
     7.1 --- a/test/tools/javac/lambda/LambdaConversionTest.java	Fri Nov 30 15:14:12 2012 +0000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,246 +0,0 @@
     7.4 -/*
     7.5 - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     7.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 - *
     7.8 - * This code is free software; you can redistribute it and/or modify it
     7.9 - * under the terms of the GNU General Public License version 2 only, as
    7.10 - * published by the Free Software Foundation.
    7.11 - *
    7.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
    7.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.15 - * version 2 for more details (a copy is included in the LICENSE file that
    7.16 - * accompanied this code).
    7.17 - *
    7.18 - * You should have received a copy of the GNU General Public License version
    7.19 - * 2 along with this work; if not, write to the Free Software Foundation,
    7.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.21 - *
    7.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.23 - * or visit www.oracle.com if you need additional information or have any
    7.24 - * questions.
    7.25 - */
    7.26 -
    7.27 -/**
    7.28 - * @test
    7.29 - * @bug 8003280
    7.30 - * @summary Add lambda tests
    7.31 - *  perform several automated checks in lambda conversion, esp. around accessibility
    7.32 - * @author  Maurizio Cimadamore
    7.33 - * @run main LambdaConversionTest
    7.34 - */
    7.35 -
    7.36 -import com.sun.source.util.JavacTask;
    7.37 -import java.net.URI;
    7.38 -import java.util.Arrays;
    7.39 -import javax.tools.Diagnostic;
    7.40 -import javax.tools.JavaCompiler;
    7.41 -import javax.tools.JavaFileObject;
    7.42 -import javax.tools.SimpleJavaFileObject;
    7.43 -import javax.tools.ToolProvider;
    7.44 -
    7.45 -public class LambdaConversionTest {
    7.46 -
    7.47 -    enum PackageKind {
    7.48 -        NO_PKG(""),
    7.49 -        PKG_A("a");
    7.50 -
    7.51 -        String pkg;
    7.52 -
    7.53 -        PackageKind(String pkg) {
    7.54 -            this.pkg = pkg;
    7.55 -        }
    7.56 -
    7.57 -        String getPkgDecl() {
    7.58 -            return this == NO_PKG ?
    7.59 -                "" :
    7.60 -                "package " + pkg + ";";
    7.61 -        }
    7.62 -
    7.63 -        String getImportStat() {
    7.64 -            return this == NO_PKG ?
    7.65 -                "" :
    7.66 -                "import " + pkg + ".*;";
    7.67 -        }
    7.68 -    }
    7.69 -
    7.70 -    enum SamKind {
    7.71 -        CLASS("public class Sam {  }"),
    7.72 -        ABSTACT_CLASS("public abstract class Sam {  }"),
    7.73 -        ANNOTATION("public @interface Sam {  }"),
    7.74 -        ENUM("public enum Sam { }"),
    7.75 -        INTERFACE("public interface Sam { \n #METH; \n }");
    7.76 -
    7.77 -        String sam_str;
    7.78 -
    7.79 -        SamKind(String sam_str) {
    7.80 -            this.sam_str = sam_str;
    7.81 -        }
    7.82 -
    7.83 -        String getSam(String methStr) {
    7.84 -            return sam_str.replaceAll("#METH", methStr);
    7.85 -        }
    7.86 -    }
    7.87 -
    7.88 -    enum ModifierKind {
    7.89 -        PUBLIC("public"),
    7.90 -        PACKAGE("");
    7.91 -
    7.92 -        String modifier_str;
    7.93 -
    7.94 -        ModifierKind(String modifier_str) {
    7.95 -            this.modifier_str = modifier_str;
    7.96 -        }
    7.97 -
    7.98 -        boolean stricterThan(ModifierKind that) {
    7.99 -            return this.ordinal() > that.ordinal();
   7.100 -        }
   7.101 -    }
   7.102 -
   7.103 -    enum TypeKind {
   7.104 -        EXCEPTION("Exception"),
   7.105 -        PKG_CLASS("PackageClass");
   7.106 -
   7.107 -        String typeStr;
   7.108 -
   7.109 -        private TypeKind(String typeStr) {
   7.110 -            this.typeStr = typeStr;
   7.111 -        }
   7.112 -    }
   7.113 -
   7.114 -    enum MethodKind {
   7.115 -        NONE(""),
   7.116 -        NON_GENERIC("public #R m(#ARG s) throws #T;"),
   7.117 -        GENERIC("public <X> #R m(#ARG s) throws #T;");
   7.118 -
   7.119 -        String methodTemplate;
   7.120 -
   7.121 -        private MethodKind(String methodTemplate) {
   7.122 -            this.methodTemplate = methodTemplate;
   7.123 -        }
   7.124 -
   7.125 -        String getMethod(TypeKind retType, TypeKind argType, TypeKind thrownType) {
   7.126 -            return methodTemplate.replaceAll("#R", retType.typeStr).
   7.127 -                    replaceAll("#ARG", argType.typeStr).
   7.128 -                    replaceAll("#T", thrownType.typeStr);
   7.129 -        }
   7.130 -    }
   7.131 -
   7.132 -    public static void main(String[] args) throws Exception {
   7.133 -        for (PackageKind samPkg : PackageKind.values()) {
   7.134 -            for (ModifierKind modKind : ModifierKind.values()) {
   7.135 -                for (SamKind samKind : SamKind.values()) {
   7.136 -                    for (MethodKind meth : MethodKind.values()) {
   7.137 -                        for (TypeKind retType : TypeKind.values()) {
   7.138 -                            for (TypeKind argType : TypeKind.values()) {
   7.139 -                                for (TypeKind thrownType : TypeKind.values()) {
   7.140 -                                    new LambdaConversionTest(samPkg, modKind, samKind,
   7.141 -                                            meth, retType, argType, thrownType).test();
   7.142 -                                }
   7.143 -                            }
   7.144 -                        }
   7.145 -                    }
   7.146 -                }
   7.147 -            }
   7.148 -        }
   7.149 -    }
   7.150 -
   7.151 -    PackageKind samPkg;
   7.152 -    ModifierKind modKind;
   7.153 -    SamKind samKind;
   7.154 -    MethodKind meth;
   7.155 -    TypeKind retType;
   7.156 -    TypeKind argType;
   7.157 -    TypeKind thrownType;
   7.158 -
   7.159 -    SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
   7.160 -        public String toString() {
   7.161 -            return template.replaceAll("#P", samPkg.getPkgDecl()).
   7.162 -                    replaceAll("#C", samKind.getSam(meth.getMethod(retType, argType, thrownType)));
   7.163 -        }
   7.164 -    };
   7.165 -
   7.166 -    SourceFile pkgClassSourceFile = new SourceFile("PackageClass.java",
   7.167 -                                                   "#P\n #M class PackageClass extends Exception { }") {
   7.168 -        public String toString() {
   7.169 -            return template.replaceAll("#P", samPkg.getPkgDecl()).
   7.170 -                    replaceAll("#M", modKind.modifier_str);
   7.171 -        }
   7.172 -    };
   7.173 -
   7.174 -    SourceFile clientSourceFile = new SourceFile("Client.java",
   7.175 -                                                 "#I\n class Client { Sam s = x -> null; }") {
   7.176 -        public String toString() {
   7.177 -            return template.replaceAll("#I", samPkg.getImportStat());
   7.178 -        }
   7.179 -    };
   7.180 -
   7.181 -    LambdaConversionTest(PackageKind samPkg, ModifierKind modKind, SamKind samKind,
   7.182 -            MethodKind meth, TypeKind retType, TypeKind argType, TypeKind thrownType) {
   7.183 -        this.samPkg = samPkg;
   7.184 -        this.modKind = modKind;
   7.185 -        this.samKind = samKind;
   7.186 -        this.meth = meth;
   7.187 -        this.retType = retType;
   7.188 -        this.argType = argType;
   7.189 -        this.thrownType = thrownType;
   7.190 -    }
   7.191 -
   7.192 -    void test() throws Exception {
   7.193 -        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   7.194 -        DiagnosticChecker dc = new DiagnosticChecker();
   7.195 -        JavacTask ct = (JavacTask)tool.getTask(null, null, dc,
   7.196 -                null, null, Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
   7.197 -        ct.analyze();
   7.198 -        if (dc.errorFound == checkSamConversion()) {
   7.199 -            throw new AssertionError(samSourceFile + "\n\n" + pkgClassSourceFile + "\n\n" + clientSourceFile);
   7.200 -        }
   7.201 -    }
   7.202 -
   7.203 -    boolean checkSamConversion() {
   7.204 -        if (samKind != SamKind.INTERFACE) {
   7.205 -            //sam type must be an interface
   7.206 -            return false;
   7.207 -        } else if (meth != MethodKind.NON_GENERIC) {
   7.208 -            //target method must be non-generic
   7.209 -            return false;
   7.210 -        } else if (samPkg != PackageKind.NO_PKG &&
   7.211 -                modKind != ModifierKind.PUBLIC &&
   7.212 -                (retType == TypeKind.PKG_CLASS ||
   7.213 -                argType == TypeKind.PKG_CLASS ||
   7.214 -                thrownType == TypeKind.PKG_CLASS)) {
   7.215 -            //target must not contain inaccessible types
   7.216 -            return false;
   7.217 -        } else {
   7.218 -            return true;
   7.219 -        }
   7.220 -    }
   7.221 -
   7.222 -    abstract class SourceFile extends SimpleJavaFileObject {
   7.223 -
   7.224 -        protected String template;
   7.225 -
   7.226 -        public SourceFile(String filename, String template) {
   7.227 -            super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
   7.228 -            this.template = template;
   7.229 -        }
   7.230 -
   7.231 -        @Override
   7.232 -        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   7.233 -            return toString();
   7.234 -        }
   7.235 -
   7.236 -        public abstract String toString();
   7.237 -    }
   7.238 -
   7.239 -    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   7.240 -
   7.241 -        boolean errorFound = false;
   7.242 -
   7.243 -        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   7.244 -            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
   7.245 -                errorFound = true;
   7.246 -            }
   7.247 -        }
   7.248 -    }
   7.249 -}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/test/tools/javac/lambda/MethodReference57.java	Fri Nov 30 15:14:25 2012 +0000
     8.3 @@ -0,0 +1,41 @@
     8.4 +/*
     8.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.
    8.11 + *
    8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.15 + * version 2 for more details (a copy is included in the LICENSE file that
    8.16 + * accompanied this code).
    8.17 + *
    8.18 + * You should have received a copy of the GNU General Public License version
    8.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.21 + *
    8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.23 + * or visit www.oracle.com if you need additional information or have any
    8.24 + * questions.
    8.25 + */
    8.26 +
    8.27 +/*
    8.28 + * @test
    8.29 + * @bug 8004102
    8.30 + * @summary Add support for generic functional descriptors
    8.31 + * @compile MethodReference57.java
    8.32 + */
    8.33 +class MethodReference57 {
    8.34 +
    8.35 +    interface F {
    8.36 +        <X> void m();
    8.37 +    }
    8.38 +
    8.39 +    void test() {
    8.40 +        F f = this::g; //ok
    8.41 +    }
    8.42 +
    8.43 +    void g() { }
    8.44 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/tools/javac/lambda/MethodReference58.java	Fri Nov 30 15:14:25 2012 +0000
     9.3 @@ -0,0 +1,46 @@
     9.4 +/*
     9.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.
    9.11 + *
    9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.15 + * version 2 for more details (a copy is included in the LICENSE file that
    9.16 + * accompanied this code).
    9.17 + *
    9.18 + * You should have received a copy of the GNU General Public License version
    9.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.21 + *
    9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.23 + * or visit www.oracle.com if you need additional information or have any
    9.24 + * questions.
    9.25 + */
    9.26 +
    9.27 +/*
    9.28 + * @test
    9.29 + * @bug 8004102
    9.30 + * @summary Add support for generic functional descriptors
    9.31 + * @compile/fail/ref=MethodReference58.out -XDrawDiagnostics MethodReference58.java
    9.32 + */
    9.33 +class MethodReference58 {
    9.34 +
    9.35 +    interface F_Object {
    9.36 +        <X> void m(X x);
    9.37 +    }
    9.38 +
    9.39 +    interface F_Integer {
    9.40 +        <X extends Integer> void m(X x);
    9.41 +    }
    9.42 +
    9.43 +    void test() {
    9.44 +        F_Object f1 = this::g; //incompatible bounds
    9.45 +        F_Integer f2 = this::g; //ok
    9.46 +    }
    9.47 +
    9.48 +    <Z extends Number> void g(Z z) { }
    9.49 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/test/tools/javac/lambda/MethodReference58.out	Fri Nov 30 15:14:25 2012 +0000
    10.3 @@ -0,0 +1,2 @@
    10.4 +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)))
    10.5 +1 error

mercurial