test/tools/javac/lambda/FunctionalInterfaceConversionTest.java

Tue, 08 Jan 2013 13:47:57 +0000

author
vromero
date
Tue, 08 Jan 2013 13:47:57 +0000
changeset 1482
954541f13717
parent 1434
34d1ebaf4645
child 1520
5c956be64b9e
permissions
-rw-r--r--

8005167: execution time of combo tests in javac should be improved
Reviewed-by: jjg, jjh

mcimadamore@1434 1 /*
vromero@1482 2 * Copyright (c) 2012, 2013, 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
vromero@1482 30 * @library ../lib
vromero@1482 31 * @build JavacTestingAbstractThreadedTest
mcimadamore@1434 32 * @run main FunctionalInterfaceConversionTest
mcimadamore@1434 33 */
mcimadamore@1434 34
vromero@1482 35 import java.io.IOException;
mcimadamore@1434 36 import java.net.URI;
mcimadamore@1434 37 import java.util.Arrays;
mcimadamore@1434 38 import javax.tools.Diagnostic;
mcimadamore@1434 39 import javax.tools.JavaCompiler;
mcimadamore@1434 40 import javax.tools.JavaFileObject;
mcimadamore@1434 41 import javax.tools.SimpleJavaFileObject;
mcimadamore@1434 42 import javax.tools.ToolProvider;
vromero@1482 43 import com.sun.source.util.JavacTask;
mcimadamore@1434 44
vromero@1482 45 public class FunctionalInterfaceConversionTest
vromero@1482 46 extends JavacTestingAbstractThreadedTest
vromero@1482 47 implements Runnable {
mcimadamore@1434 48
mcimadamore@1434 49 enum PackageKind {
mcimadamore@1434 50 NO_PKG(""),
mcimadamore@1434 51 PKG_A("a");
mcimadamore@1434 52
mcimadamore@1434 53 String pkg;
mcimadamore@1434 54
mcimadamore@1434 55 PackageKind(String pkg) {
mcimadamore@1434 56 this.pkg = pkg;
mcimadamore@1434 57 }
mcimadamore@1434 58
mcimadamore@1434 59 String getPkgDecl() {
mcimadamore@1434 60 return this == NO_PKG ?
mcimadamore@1434 61 "" :
mcimadamore@1434 62 "package " + pkg + ";";
mcimadamore@1434 63 }
mcimadamore@1434 64
mcimadamore@1434 65 String getImportStat() {
mcimadamore@1434 66 return this == NO_PKG ?
mcimadamore@1434 67 "" :
mcimadamore@1434 68 "import " + pkg + ".*;";
mcimadamore@1434 69 }
mcimadamore@1434 70 }
mcimadamore@1434 71
mcimadamore@1434 72 enum SamKind {
mcimadamore@1434 73 CLASS("public class Sam { }"),
mcimadamore@1434 74 ABSTACT_CLASS("public abstract class Sam { }"),
mcimadamore@1434 75 ANNOTATION("public @interface Sam { }"),
mcimadamore@1434 76 ENUM("public enum Sam { }"),
mcimadamore@1434 77 INTERFACE("public interface Sam { \n #METH; \n }");
mcimadamore@1434 78
mcimadamore@1434 79 String sam_str;
mcimadamore@1434 80
mcimadamore@1434 81 SamKind(String sam_str) {
mcimadamore@1434 82 this.sam_str = sam_str;
mcimadamore@1434 83 }
mcimadamore@1434 84
mcimadamore@1434 85 String getSam(String methStr) {
mcimadamore@1434 86 return sam_str.replaceAll("#METH", methStr);
mcimadamore@1434 87 }
mcimadamore@1434 88 }
mcimadamore@1434 89
mcimadamore@1434 90 enum ModifierKind {
mcimadamore@1434 91 PUBLIC("public"),
mcimadamore@1434 92 PACKAGE("");
mcimadamore@1434 93
mcimadamore@1434 94 String modifier_str;
mcimadamore@1434 95
mcimadamore@1434 96 ModifierKind(String modifier_str) {
mcimadamore@1434 97 this.modifier_str = modifier_str;
mcimadamore@1434 98 }
mcimadamore@1434 99
mcimadamore@1434 100 boolean stricterThan(ModifierKind that) {
mcimadamore@1434 101 return this.ordinal() > that.ordinal();
mcimadamore@1434 102 }
mcimadamore@1434 103 }
mcimadamore@1434 104
mcimadamore@1434 105 enum TypeKind {
mcimadamore@1434 106 EXCEPTION("Exception"),
mcimadamore@1434 107 PKG_CLASS("PackageClass");
mcimadamore@1434 108
mcimadamore@1434 109 String typeStr;
mcimadamore@1434 110
mcimadamore@1434 111 private TypeKind(String typeStr) {
mcimadamore@1434 112 this.typeStr = typeStr;
mcimadamore@1434 113 }
mcimadamore@1434 114 }
mcimadamore@1434 115
mcimadamore@1434 116 enum ExprKind {
mcimadamore@1434 117 LAMBDA("x -> null"),
mcimadamore@1434 118 MREF("this::m");
mcimadamore@1434 119
mcimadamore@1434 120 String exprStr;
mcimadamore@1434 121
mcimadamore@1434 122 private ExprKind(String exprStr) {
mcimadamore@1434 123 this.exprStr = exprStr;
mcimadamore@1434 124 }
mcimadamore@1434 125 }
mcimadamore@1434 126
mcimadamore@1434 127 enum MethodKind {
mcimadamore@1434 128 NONE(""),
mcimadamore@1434 129 NON_GENERIC("public abstract #R m(#ARG s) throws #T;"),
mcimadamore@1434 130 GENERIC("public abstract <X> #R m(#ARG s) throws #T;");
mcimadamore@1434 131
mcimadamore@1434 132 String methodTemplate;
mcimadamore@1434 133
mcimadamore@1434 134 private MethodKind(String methodTemplate) {
mcimadamore@1434 135 this.methodTemplate = methodTemplate;
mcimadamore@1434 136 }
mcimadamore@1434 137
mcimadamore@1434 138 String getMethod(TypeKind retType, TypeKind argType, TypeKind thrownType) {
mcimadamore@1434 139 return methodTemplate.replaceAll("#R", retType.typeStr).
mcimadamore@1434 140 replaceAll("#ARG", argType.typeStr).
mcimadamore@1434 141 replaceAll("#T", thrownType.typeStr);
mcimadamore@1434 142 }
mcimadamore@1434 143 }
mcimadamore@1434 144
mcimadamore@1434 145 public static void main(String[] args) throws Exception {
mcimadamore@1434 146 for (PackageKind samPkg : PackageKind.values()) {
mcimadamore@1434 147 for (ModifierKind modKind : ModifierKind.values()) {
mcimadamore@1434 148 for (SamKind samKind : SamKind.values()) {
mcimadamore@1434 149 for (MethodKind samMeth : MethodKind.values()) {
mcimadamore@1434 150 for (MethodKind clientMeth : MethodKind.values()) {
mcimadamore@1434 151 for (TypeKind retType : TypeKind.values()) {
mcimadamore@1434 152 for (TypeKind argType : TypeKind.values()) {
mcimadamore@1434 153 for (TypeKind thrownType : TypeKind.values()) {
mcimadamore@1434 154 for (ExprKind exprKind : ExprKind.values()) {
vromero@1482 155 pool.execute(
vromero@1482 156 new FunctionalInterfaceConversionTest(
vromero@1482 157 samPkg, modKind, samKind,
vromero@1482 158 samMeth, clientMeth, retType,
vromero@1482 159 argType, thrownType, exprKind));
mcimadamore@1434 160 }
mcimadamore@1434 161 }
mcimadamore@1434 162 }
mcimadamore@1434 163 }
mcimadamore@1434 164 }
mcimadamore@1434 165 }
mcimadamore@1434 166 }
mcimadamore@1434 167 }
mcimadamore@1434 168 }
vromero@1482 169
vromero@1482 170 checkAfterExec(false);
mcimadamore@1434 171 }
mcimadamore@1434 172
mcimadamore@1434 173 PackageKind samPkg;
mcimadamore@1434 174 ModifierKind modKind;
mcimadamore@1434 175 SamKind samKind;
mcimadamore@1434 176 MethodKind samMeth;
mcimadamore@1434 177 MethodKind clientMeth;
mcimadamore@1434 178 TypeKind retType;
mcimadamore@1434 179 TypeKind argType;
mcimadamore@1434 180 TypeKind thrownType;
mcimadamore@1434 181 ExprKind exprKind;
mcimadamore@1434 182 DiagnosticChecker dc;
mcimadamore@1434 183
mcimadamore@1434 184 SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
vromero@1482 185 @Override
mcimadamore@1434 186 public String toString() {
mcimadamore@1434 187 return template.replaceAll("#P", samPkg.getPkgDecl()).
vromero@1482 188 replaceAll("#C", samKind.getSam(
vromero@1482 189 samMeth.getMethod(retType, argType, thrownType)));
mcimadamore@1434 190 }
mcimadamore@1434 191 };
mcimadamore@1434 192
vromero@1482 193 SourceFile pkgClassSourceFile =
vromero@1482 194 new SourceFile("PackageClass.java",
vromero@1482 195 "#P\n #M class PackageClass extends Exception { }") {
vromero@1482 196 @Override
mcimadamore@1434 197 public String toString() {
mcimadamore@1434 198 return template.replaceAll("#P", samPkg.getPkgDecl()).
mcimadamore@1434 199 replaceAll("#M", modKind.modifier_str);
mcimadamore@1434 200 }
mcimadamore@1434 201 };
mcimadamore@1434 202
vromero@1482 203 SourceFile clientSourceFile =
vromero@1482 204 new SourceFile("Client.java",
vromero@1482 205 "#I\n abstract class Client { \n" +
vromero@1482 206 " Sam s = #E;\n" +
vromero@1482 207 " #M \n }") {
vromero@1482 208 @Override
mcimadamore@1434 209 public String toString() {
mcimadamore@1434 210 return template.replaceAll("#I", samPkg.getImportStat())
mcimadamore@1434 211 .replaceAll("#E", exprKind.exprStr)
mcimadamore@1434 212 .replaceAll("#M", clientMeth.getMethod(retType, argType, thrownType));
mcimadamore@1434 213 }
mcimadamore@1434 214 };
mcimadamore@1434 215
vromero@1482 216 FunctionalInterfaceConversionTest(PackageKind samPkg, ModifierKind modKind,
vromero@1482 217 SamKind samKind, MethodKind samMeth, MethodKind clientMeth,
vromero@1482 218 TypeKind retType, TypeKind argType, TypeKind thrownType,
vromero@1482 219 ExprKind exprKind) {
mcimadamore@1434 220 this.samPkg = samPkg;
mcimadamore@1434 221 this.modKind = modKind;
mcimadamore@1434 222 this.samKind = samKind;
mcimadamore@1434 223 this.samMeth = samMeth;
mcimadamore@1434 224 this.clientMeth = clientMeth;
mcimadamore@1434 225 this.retType = retType;
mcimadamore@1434 226 this.argType = argType;
mcimadamore@1434 227 this.thrownType = thrownType;
mcimadamore@1434 228 this.exprKind = exprKind;
mcimadamore@1434 229 this.dc = new DiagnosticChecker();
mcimadamore@1434 230 }
mcimadamore@1434 231
vromero@1482 232 @Override
vromero@1482 233 public void run() {
vromero@1482 234 final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
vromero@1482 235
vromero@1482 236 JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), dc, null, null,
vromero@1482 237 Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
vromero@1482 238 try {
vromero@1482 239 ct.analyze();
vromero@1482 240 } catch (IOException ex) {
vromero@1482 241 throw new AssertionError("Test failing with cause", ex.getCause());
vromero@1482 242 }
mcimadamore@1434 243 if (dc.errorFound == checkSamConversion()) {
vromero@1482 244 throw new AssertionError(samSourceFile + "\n\n" +
vromero@1482 245 pkgClassSourceFile + "\n\n" + clientSourceFile);
mcimadamore@1434 246 }
mcimadamore@1434 247 }
mcimadamore@1434 248
mcimadamore@1434 249 boolean checkSamConversion() {
mcimadamore@1434 250 if (samKind != SamKind.INTERFACE) {
mcimadamore@1434 251 //sam type must be an interface
mcimadamore@1434 252 return false;
mcimadamore@1434 253 } else if (samMeth == MethodKind.NONE) {
mcimadamore@1434 254 //interface must have at least a method
mcimadamore@1434 255 return false;
mcimadamore@1434 256 } else if (exprKind == ExprKind.LAMBDA &&
mcimadamore@1434 257 samMeth != MethodKind.NON_GENERIC) {
mcimadamore@1434 258 //target method for lambda must be non-generic
mcimadamore@1434 259 return false;
mcimadamore@1434 260 } else if (exprKind == ExprKind.MREF &&
mcimadamore@1434 261 clientMeth == MethodKind.NONE) {
mcimadamore@1434 262 return false;
mcimadamore@1434 263 } else if (samPkg != PackageKind.NO_PKG &&
mcimadamore@1434 264 modKind != ModifierKind.PUBLIC &&
mcimadamore@1434 265 (retType == TypeKind.PKG_CLASS ||
mcimadamore@1434 266 argType == TypeKind.PKG_CLASS ||
mcimadamore@1434 267 thrownType == TypeKind.PKG_CLASS)) {
mcimadamore@1434 268 //target must not contain inaccessible types
mcimadamore@1434 269 return false;
mcimadamore@1434 270 } else {
mcimadamore@1434 271 return true;
mcimadamore@1434 272 }
mcimadamore@1434 273 }
mcimadamore@1434 274
mcimadamore@1434 275 abstract class SourceFile extends SimpleJavaFileObject {
mcimadamore@1434 276
mcimadamore@1434 277 protected String template;
mcimadamore@1434 278
mcimadamore@1434 279 public SourceFile(String filename, String template) {
mcimadamore@1434 280 super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
mcimadamore@1434 281 this.template = template;
mcimadamore@1434 282 }
mcimadamore@1434 283
mcimadamore@1434 284 @Override
mcimadamore@1434 285 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
mcimadamore@1434 286 return toString();
mcimadamore@1434 287 }
mcimadamore@1434 288
vromero@1482 289 @Override
mcimadamore@1434 290 public abstract String toString();
mcimadamore@1434 291 }
mcimadamore@1434 292
vromero@1482 293 static class DiagnosticChecker
vromero@1482 294 implements javax.tools.DiagnosticListener<JavaFileObject> {
mcimadamore@1434 295
mcimadamore@1434 296 boolean errorFound = false;
mcimadamore@1434 297
vromero@1482 298 @Override
mcimadamore@1434 299 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
mcimadamore@1434 300 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
mcimadamore@1434 301 errorFound = true;
mcimadamore@1434 302 }
mcimadamore@1434 303 }
mcimadamore@1434 304 }
mcimadamore@1434 305 }

mercurial