test/tools/javac/lambda/FunctionalInterfaceConversionTest.java

Thu, 31 Aug 2017 15:17:03 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:17:03 +0800
changeset 2525
2eb010b6cb22
parent 2354
b33835c5d96a
parent 0
959103a6100f
permissions
-rw-r--r--

merge

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

mercurial