test/tools/javac/lambda/FunctionalInterfaceConversionTest.java

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

author
mcimadamore
date
Fri, 30 Nov 2012 15:14:25 +0000
changeset 1434
34d1ebaf4645
child 1482
954541f13717
permissions
-rw-r--r--

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

mcimadamore@1434 1 /*
mcimadamore@1434 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
mcimadamore@1434 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mcimadamore@1434 4 *
mcimadamore@1434 5 * This code is free software; you can redistribute it and/or modify it
mcimadamore@1434 6 * under the terms of the GNU General Public License version 2 only, as
mcimadamore@1434 7 * published by the Free Software Foundation.
mcimadamore@1434 8 *
mcimadamore@1434 9 * This code is distributed in the hope that it will be useful, but WITHOUT
mcimadamore@1434 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mcimadamore@1434 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mcimadamore@1434 12 * version 2 for more details (a copy is included in the LICENSE file that
mcimadamore@1434 13 * accompanied this code).
mcimadamore@1434 14 *
mcimadamore@1434 15 * You should have received a copy of the GNU General Public License version
mcimadamore@1434 16 * 2 along with this work; if not, write to the Free Software Foundation,
mcimadamore@1434 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mcimadamore@1434 18 *
mcimadamore@1434 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mcimadamore@1434 20 * or visit www.oracle.com if you need additional information or have any
mcimadamore@1434 21 * questions.
mcimadamore@1434 22 */
mcimadamore@1434 23
mcimadamore@1434 24 /**
mcimadamore@1434 25 * @test
mcimadamore@1434 26 * @bug 8003280 8004102
mcimadamore@1434 27 * @summary Add lambda tests
mcimadamore@1434 28 * perform several automated checks in lambda conversion, esp. around accessibility
mcimadamore@1434 29 * @author Maurizio Cimadamore
mcimadamore@1434 30 * @run main FunctionalInterfaceConversionTest
mcimadamore@1434 31 */
mcimadamore@1434 32
mcimadamore@1434 33 import com.sun.source.util.JavacTask;
mcimadamore@1434 34 import java.net.URI;
mcimadamore@1434 35 import java.util.Arrays;
mcimadamore@1434 36 import javax.tools.Diagnostic;
mcimadamore@1434 37 import javax.tools.JavaCompiler;
mcimadamore@1434 38 import javax.tools.JavaFileObject;
mcimadamore@1434 39 import javax.tools.SimpleJavaFileObject;
mcimadamore@1434 40 import javax.tools.StandardJavaFileManager;
mcimadamore@1434 41 import javax.tools.ToolProvider;
mcimadamore@1434 42
mcimadamore@1434 43 public class FunctionalInterfaceConversionTest {
mcimadamore@1434 44
mcimadamore@1434 45 enum PackageKind {
mcimadamore@1434 46 NO_PKG(""),
mcimadamore@1434 47 PKG_A("a");
mcimadamore@1434 48
mcimadamore@1434 49 String pkg;
mcimadamore@1434 50
mcimadamore@1434 51 PackageKind(String pkg) {
mcimadamore@1434 52 this.pkg = pkg;
mcimadamore@1434 53 }
mcimadamore@1434 54
mcimadamore@1434 55 String getPkgDecl() {
mcimadamore@1434 56 return this == NO_PKG ?
mcimadamore@1434 57 "" :
mcimadamore@1434 58 "package " + pkg + ";";
mcimadamore@1434 59 }
mcimadamore@1434 60
mcimadamore@1434 61 String getImportStat() {
mcimadamore@1434 62 return this == NO_PKG ?
mcimadamore@1434 63 "" :
mcimadamore@1434 64 "import " + pkg + ".*;";
mcimadamore@1434 65 }
mcimadamore@1434 66 }
mcimadamore@1434 67
mcimadamore@1434 68 enum SamKind {
mcimadamore@1434 69 CLASS("public class Sam { }"),
mcimadamore@1434 70 ABSTACT_CLASS("public abstract class Sam { }"),
mcimadamore@1434 71 ANNOTATION("public @interface Sam { }"),
mcimadamore@1434 72 ENUM("public enum Sam { }"),
mcimadamore@1434 73 INTERFACE("public interface Sam { \n #METH; \n }");
mcimadamore@1434 74
mcimadamore@1434 75 String sam_str;
mcimadamore@1434 76
mcimadamore@1434 77 SamKind(String sam_str) {
mcimadamore@1434 78 this.sam_str = sam_str;
mcimadamore@1434 79 }
mcimadamore@1434 80
mcimadamore@1434 81 String getSam(String methStr) {
mcimadamore@1434 82 return sam_str.replaceAll("#METH", methStr);
mcimadamore@1434 83 }
mcimadamore@1434 84 }
mcimadamore@1434 85
mcimadamore@1434 86 enum ModifierKind {
mcimadamore@1434 87 PUBLIC("public"),
mcimadamore@1434 88 PACKAGE("");
mcimadamore@1434 89
mcimadamore@1434 90 String modifier_str;
mcimadamore@1434 91
mcimadamore@1434 92 ModifierKind(String modifier_str) {
mcimadamore@1434 93 this.modifier_str = modifier_str;
mcimadamore@1434 94 }
mcimadamore@1434 95
mcimadamore@1434 96 boolean stricterThan(ModifierKind that) {
mcimadamore@1434 97 return this.ordinal() > that.ordinal();
mcimadamore@1434 98 }
mcimadamore@1434 99 }
mcimadamore@1434 100
mcimadamore@1434 101 enum TypeKind {
mcimadamore@1434 102 EXCEPTION("Exception"),
mcimadamore@1434 103 PKG_CLASS("PackageClass");
mcimadamore@1434 104
mcimadamore@1434 105 String typeStr;
mcimadamore@1434 106
mcimadamore@1434 107 private TypeKind(String typeStr) {
mcimadamore@1434 108 this.typeStr = typeStr;
mcimadamore@1434 109 }
mcimadamore@1434 110 }
mcimadamore@1434 111
mcimadamore@1434 112 enum ExprKind {
mcimadamore@1434 113 LAMBDA("x -> null"),
mcimadamore@1434 114 MREF("this::m");
mcimadamore@1434 115
mcimadamore@1434 116 String exprStr;
mcimadamore@1434 117
mcimadamore@1434 118 private ExprKind(String exprStr) {
mcimadamore@1434 119 this.exprStr = exprStr;
mcimadamore@1434 120 }
mcimadamore@1434 121 }
mcimadamore@1434 122
mcimadamore@1434 123 enum MethodKind {
mcimadamore@1434 124 NONE(""),
mcimadamore@1434 125 NON_GENERIC("public abstract #R m(#ARG s) throws #T;"),
mcimadamore@1434 126 GENERIC("public abstract <X> #R m(#ARG s) throws #T;");
mcimadamore@1434 127
mcimadamore@1434 128 String methodTemplate;
mcimadamore@1434 129
mcimadamore@1434 130 private MethodKind(String methodTemplate) {
mcimadamore@1434 131 this.methodTemplate = methodTemplate;
mcimadamore@1434 132 }
mcimadamore@1434 133
mcimadamore@1434 134 String getMethod(TypeKind retType, TypeKind argType, TypeKind thrownType) {
mcimadamore@1434 135 return methodTemplate.replaceAll("#R", retType.typeStr).
mcimadamore@1434 136 replaceAll("#ARG", argType.typeStr).
mcimadamore@1434 137 replaceAll("#T", thrownType.typeStr);
mcimadamore@1434 138 }
mcimadamore@1434 139 }
mcimadamore@1434 140
mcimadamore@1434 141 public static void main(String[] args) throws Exception {
mcimadamore@1434 142 final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
mcimadamore@1434 143 StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
mcimadamore@1434 144 for (PackageKind samPkg : PackageKind.values()) {
mcimadamore@1434 145 for (ModifierKind modKind : ModifierKind.values()) {
mcimadamore@1434 146 for (SamKind samKind : SamKind.values()) {
mcimadamore@1434 147 for (MethodKind samMeth : MethodKind.values()) {
mcimadamore@1434 148 for (MethodKind clientMeth : MethodKind.values()) {
mcimadamore@1434 149 for (TypeKind retType : TypeKind.values()) {
mcimadamore@1434 150 for (TypeKind argType : TypeKind.values()) {
mcimadamore@1434 151 for (TypeKind thrownType : TypeKind.values()) {
mcimadamore@1434 152 for (ExprKind exprKind : ExprKind.values()) {
mcimadamore@1434 153 new FunctionalInterfaceConversionTest(samPkg, modKind, samKind,
mcimadamore@1434 154 samMeth, clientMeth, retType, argType, thrownType, exprKind).test(comp, fm);
mcimadamore@1434 155 }
mcimadamore@1434 156 }
mcimadamore@1434 157 }
mcimadamore@1434 158 }
mcimadamore@1434 159 }
mcimadamore@1434 160 }
mcimadamore@1434 161 }
mcimadamore@1434 162 }
mcimadamore@1434 163 }
mcimadamore@1434 164 }
mcimadamore@1434 165
mcimadamore@1434 166 PackageKind samPkg;
mcimadamore@1434 167 ModifierKind modKind;
mcimadamore@1434 168 SamKind samKind;
mcimadamore@1434 169 MethodKind samMeth;
mcimadamore@1434 170 MethodKind clientMeth;
mcimadamore@1434 171 TypeKind retType;
mcimadamore@1434 172 TypeKind argType;
mcimadamore@1434 173 TypeKind thrownType;
mcimadamore@1434 174 ExprKind exprKind;
mcimadamore@1434 175 DiagnosticChecker dc;
mcimadamore@1434 176
mcimadamore@1434 177 SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
mcimadamore@1434 178 public String toString() {
mcimadamore@1434 179 return template.replaceAll("#P", samPkg.getPkgDecl()).
mcimadamore@1434 180 replaceAll("#C", samKind.getSam(samMeth.getMethod(retType, argType, thrownType)));
mcimadamore@1434 181 }
mcimadamore@1434 182 };
mcimadamore@1434 183
mcimadamore@1434 184 SourceFile pkgClassSourceFile = new SourceFile("PackageClass.java",
mcimadamore@1434 185 "#P\n #M class PackageClass extends Exception { }") {
mcimadamore@1434 186 public String toString() {
mcimadamore@1434 187 return template.replaceAll("#P", samPkg.getPkgDecl()).
mcimadamore@1434 188 replaceAll("#M", modKind.modifier_str);
mcimadamore@1434 189 }
mcimadamore@1434 190 };
mcimadamore@1434 191
mcimadamore@1434 192 SourceFile clientSourceFile = new SourceFile("Client.java",
mcimadamore@1434 193 "#I\n abstract class Client { \n" +
mcimadamore@1434 194 " Sam s = #E;\n" +
mcimadamore@1434 195 " #M \n }") {
mcimadamore@1434 196 public String toString() {
mcimadamore@1434 197 return template.replaceAll("#I", samPkg.getImportStat())
mcimadamore@1434 198 .replaceAll("#E", exprKind.exprStr)
mcimadamore@1434 199 .replaceAll("#M", clientMeth.getMethod(retType, argType, thrownType));
mcimadamore@1434 200 }
mcimadamore@1434 201 };
mcimadamore@1434 202
mcimadamore@1434 203 FunctionalInterfaceConversionTest(PackageKind samPkg, ModifierKind modKind, SamKind samKind,
mcimadamore@1434 204 MethodKind samMeth, MethodKind clientMeth, TypeKind retType, TypeKind argType,
mcimadamore@1434 205 TypeKind thrownType, ExprKind exprKind) {
mcimadamore@1434 206 this.samPkg = samPkg;
mcimadamore@1434 207 this.modKind = modKind;
mcimadamore@1434 208 this.samKind = samKind;
mcimadamore@1434 209 this.samMeth = samMeth;
mcimadamore@1434 210 this.clientMeth = clientMeth;
mcimadamore@1434 211 this.retType = retType;
mcimadamore@1434 212 this.argType = argType;
mcimadamore@1434 213 this.thrownType = thrownType;
mcimadamore@1434 214 this.exprKind = exprKind;
mcimadamore@1434 215 this.dc = new DiagnosticChecker();
mcimadamore@1434 216 }
mcimadamore@1434 217
mcimadamore@1434 218 void test(JavaCompiler comp, StandardJavaFileManager fm) throws Exception {
mcimadamore@1434 219 JavacTask ct = (JavacTask)comp.getTask(null, fm, dc,
mcimadamore@1434 220 null, null, Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
mcimadamore@1434 221 ct.analyze();
mcimadamore@1434 222 if (dc.errorFound == checkSamConversion()) {
mcimadamore@1434 223 throw new AssertionError(samSourceFile + "\n\n" + pkgClassSourceFile + "\n\n" + clientSourceFile);
mcimadamore@1434 224 }
mcimadamore@1434 225 }
mcimadamore@1434 226
mcimadamore@1434 227 boolean checkSamConversion() {
mcimadamore@1434 228 if (samKind != SamKind.INTERFACE) {
mcimadamore@1434 229 //sam type must be an interface
mcimadamore@1434 230 return false;
mcimadamore@1434 231 } else if (samMeth == MethodKind.NONE) {
mcimadamore@1434 232 //interface must have at least a method
mcimadamore@1434 233 return false;
mcimadamore@1434 234 } else if (exprKind == ExprKind.LAMBDA &&
mcimadamore@1434 235 samMeth != MethodKind.NON_GENERIC) {
mcimadamore@1434 236 //target method for lambda must be non-generic
mcimadamore@1434 237 return false;
mcimadamore@1434 238 } else if (exprKind == ExprKind.MREF &&
mcimadamore@1434 239 clientMeth == MethodKind.NONE) {
mcimadamore@1434 240 return false;
mcimadamore@1434 241 } else if (samPkg != PackageKind.NO_PKG &&
mcimadamore@1434 242 modKind != ModifierKind.PUBLIC &&
mcimadamore@1434 243 (retType == TypeKind.PKG_CLASS ||
mcimadamore@1434 244 argType == TypeKind.PKG_CLASS ||
mcimadamore@1434 245 thrownType == TypeKind.PKG_CLASS)) {
mcimadamore@1434 246 //target must not contain inaccessible types
mcimadamore@1434 247 return false;
mcimadamore@1434 248 } else {
mcimadamore@1434 249 return true;
mcimadamore@1434 250 }
mcimadamore@1434 251 }
mcimadamore@1434 252
mcimadamore@1434 253 abstract class SourceFile extends SimpleJavaFileObject {
mcimadamore@1434 254
mcimadamore@1434 255 protected String template;
mcimadamore@1434 256
mcimadamore@1434 257 public SourceFile(String filename, String template) {
mcimadamore@1434 258 super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
mcimadamore@1434 259 this.template = template;
mcimadamore@1434 260 }
mcimadamore@1434 261
mcimadamore@1434 262 @Override
mcimadamore@1434 263 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
mcimadamore@1434 264 return toString();
mcimadamore@1434 265 }
mcimadamore@1434 266
mcimadamore@1434 267 public abstract String toString();
mcimadamore@1434 268 }
mcimadamore@1434 269
mcimadamore@1434 270 static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
mcimadamore@1434 271
mcimadamore@1434 272 boolean errorFound = false;
mcimadamore@1434 273
mcimadamore@1434 274 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
mcimadamore@1434 275 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
mcimadamore@1434 276 errorFound = true;
mcimadamore@1434 277 }
mcimadamore@1434 278 }
mcimadamore@1434 279 }
mcimadamore@1434 280 }

mercurial