test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java

Sat, 17 Nov 2012 19:01:03 +0000

author
mcimadamore
date
Sat, 17 Nov 2012 19:01:03 +0000
changeset 1415
01c9d4161882
child 1482
954541f13717
permissions
-rw-r--r--

8003280: Add lambda tests
Summary: Turn on lambda expression, method reference and default method support
Reviewed-by: jjg

mcimadamore@1415 1 /*
mcimadamore@1415 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
mcimadamore@1415 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mcimadamore@1415 4 *
mcimadamore@1415 5 * This code is free software; you can redistribute it and/or modify it
mcimadamore@1415 6 * under the terms of the GNU General Public License version 2 only, as
mcimadamore@1415 7 * published by the Free Software Foundation.
mcimadamore@1415 8 *
mcimadamore@1415 9 * This code is distributed in the hope that it will be useful, but WITHOUT
mcimadamore@1415 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mcimadamore@1415 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mcimadamore@1415 12 * version 2 for more details (a copy is included in the LICENSE file that
mcimadamore@1415 13 * accompanied this code).
mcimadamore@1415 14 *
mcimadamore@1415 15 * You should have received a copy of the GNU General Public License version
mcimadamore@1415 16 * 2 along with this work; if not, write to the Free Software Foundation,
mcimadamore@1415 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mcimadamore@1415 18 *
mcimadamore@1415 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mcimadamore@1415 20 * or visit www.oracle.com if you need additional information or have any
mcimadamore@1415 21 * questions.
mcimadamore@1415 22 */
mcimadamore@1415 23
mcimadamore@1415 24 /*
mcimadamore@1415 25 * @test
mcimadamore@1415 26 * @bug 8003280
mcimadamore@1415 27 * @summary Add lambda tests
mcimadamore@1415 28 * Automatic test for checking correctness of structural most specific test routine
mcimadamore@1415 29 * @run main/timeout=360 StructuralMostSpecificTest
mcimadamore@1415 30 */
mcimadamore@1415 31
mcimadamore@1415 32 import com.sun.source.util.JavacTask;
mcimadamore@1415 33 import com.sun.tools.javac.api.ClientCodeWrapper;
mcimadamore@1415 34 import com.sun.tools.javac.util.JCDiagnostic;
mcimadamore@1415 35 import java.net.URI;
mcimadamore@1415 36 import java.util.Arrays;
mcimadamore@1415 37 import javax.tools.Diagnostic;
mcimadamore@1415 38 import javax.tools.JavaCompiler;
mcimadamore@1415 39 import javax.tools.JavaFileObject;
mcimadamore@1415 40 import javax.tools.SimpleJavaFileObject;
mcimadamore@1415 41 import javax.tools.StandardJavaFileManager;
mcimadamore@1415 42 import javax.tools.ToolProvider;
mcimadamore@1415 43
mcimadamore@1415 44 public class StructuralMostSpecificTest {
mcimadamore@1415 45
mcimadamore@1415 46 static int checkCount = 0;
mcimadamore@1415 47
mcimadamore@1415 48 enum RetTypeKind {
mcimadamore@1415 49 SHORT("short"),
mcimadamore@1415 50 INT("int"),
mcimadamore@1415 51 OBJECT("Object"),
mcimadamore@1415 52 INTEGER("Integer"),
mcimadamore@1415 53 VOID("void"),
mcimadamore@1415 54 J_L_VOID("Void");
mcimadamore@1415 55
mcimadamore@1415 56 String retTypeStr;
mcimadamore@1415 57
mcimadamore@1415 58 RetTypeKind(String retTypeStr) {
mcimadamore@1415 59 this.retTypeStr = retTypeStr;
mcimadamore@1415 60 }
mcimadamore@1415 61
mcimadamore@1415 62 boolean moreSpecificThan(RetTypeKind rk) {
mcimadamore@1415 63 return moreSpecificThan[this.ordinal()][rk.ordinal()];
mcimadamore@1415 64 }
mcimadamore@1415 65
mcimadamore@1415 66 static boolean[][] moreSpecificThan = {
mcimadamore@1415 67 // SHORT | INT | OBJECT | INTEGER | VOID | J_L_VOID
mcimadamore@1415 68 /* SHORT */ { true , true , true , false , false , false },
mcimadamore@1415 69 /* INT */ { false , true , true , true , false , false },
mcimadamore@1415 70 /* OBJECT */ { false , false , true , false , false , false },
mcimadamore@1415 71 /* INTEGER */ { false , false , true , true , false , false },
mcimadamore@1415 72 /* VOID */ { false , false , false , false , true , true },
mcimadamore@1415 73 /* J_L_VOID */{ false , false , true , false , false , true } };
mcimadamore@1415 74 }
mcimadamore@1415 75
mcimadamore@1415 76 enum ArgTypeKind {
mcimadamore@1415 77 SHORT("short"),
mcimadamore@1415 78 INT("int"),
mcimadamore@1415 79 BOOLEAN("boolean"),
mcimadamore@1415 80 OBJECT("Object"),
mcimadamore@1415 81 INTEGER("Integer"),
mcimadamore@1415 82 DOUBLE("Double");
mcimadamore@1415 83
mcimadamore@1415 84 String argTypeStr;
mcimadamore@1415 85
mcimadamore@1415 86 ArgTypeKind(String typeStr) {
mcimadamore@1415 87 this.argTypeStr = typeStr;
mcimadamore@1415 88 }
mcimadamore@1415 89 }
mcimadamore@1415 90
mcimadamore@1415 91 enum ExceptionKind {
mcimadamore@1415 92 NONE(""),
mcimadamore@1415 93 EXCEPTION("throws Exception"),
mcimadamore@1415 94 SQL_EXCEPTION("throws java.sql.SQLException"),
mcimadamore@1415 95 IO_EXCEPTION("throws java.io.IOException");
mcimadamore@1415 96
mcimadamore@1415 97 String exceptionStr;
mcimadamore@1415 98
mcimadamore@1415 99 ExceptionKind(String exceptionStr) {
mcimadamore@1415 100 this.exceptionStr = exceptionStr;
mcimadamore@1415 101 }
mcimadamore@1415 102 }
mcimadamore@1415 103
mcimadamore@1415 104 enum LambdaReturnKind {
mcimadamore@1415 105 VOID("return;"),
mcimadamore@1415 106 SHORT("return (short)0;"),
mcimadamore@1415 107 INT("return 0;"),
mcimadamore@1415 108 INTEGER("return (Integer)null"),
mcimadamore@1415 109 NULL("return null;");
mcimadamore@1415 110
mcimadamore@1415 111 String retStr;
mcimadamore@1415 112
mcimadamore@1415 113 LambdaReturnKind(String retStr) {
mcimadamore@1415 114 this.retStr = retStr;
mcimadamore@1415 115 }
mcimadamore@1415 116
mcimadamore@1415 117 boolean compatibleWith(RetTypeKind rk) {
mcimadamore@1415 118 return compatibleWith[rk.ordinal()][ordinal()];
mcimadamore@1415 119 }
mcimadamore@1415 120
mcimadamore@1415 121 static boolean[][] compatibleWith = {
mcimadamore@1415 122 // VOID | SHORT | INT | INTEGER | NULL
mcimadamore@1415 123 /* SHORT */ { false , true , false , false , false },
mcimadamore@1415 124 /* INT */ { false , true , true , true , false },
mcimadamore@1415 125 /* OBJECT */ { false , true , true , true , true },
mcimadamore@1415 126 /* INTEGER */ { false , false , true , true , true },
mcimadamore@1415 127 /* VOID */ { true , false , false , false , false },
mcimadamore@1415 128 /* J_L_VOID */{ false , false , false , false , true } };
mcimadamore@1415 129
mcimadamore@1415 130 boolean needsConversion(RetTypeKind rk) {
mcimadamore@1415 131 return needsConversion[rk.ordinal()][ordinal()];
mcimadamore@1415 132 }
mcimadamore@1415 133
mcimadamore@1415 134 static boolean[][] needsConversion = {
mcimadamore@1415 135 // VOID | SHORT | INT | INTEGER | NULL
mcimadamore@1415 136 /* SHORT */ { false , false , false , false , false },
mcimadamore@1415 137 /* INT */ { false , false , false , true , false },
mcimadamore@1415 138 /* OBJECT */ { false , true , true , false , false },
mcimadamore@1415 139 /* INTEGER */ { false , false , true , false , false },
mcimadamore@1415 140 /* VOID */ { false , false , false , false , false },
mcimadamore@1415 141 /* J_L_VOID */{ true , false , false , false , false } };
mcimadamore@1415 142 }
mcimadamore@1415 143
mcimadamore@1415 144 public static void main(String... args) throws Exception {
mcimadamore@1415 145
mcimadamore@1415 146 //create default shared JavaCompiler - reused across multiple compilations
mcimadamore@1415 147 JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
mcimadamore@1415 148 StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
mcimadamore@1415 149
mcimadamore@1415 150 for (LambdaReturnKind lrk : LambdaReturnKind.values()) {
mcimadamore@1415 151 for (RetTypeKind rk1 : RetTypeKind.values()) {
mcimadamore@1415 152 for (RetTypeKind rk2 : RetTypeKind.values()) {
mcimadamore@1415 153 for (ExceptionKind ek1 : ExceptionKind.values()) {
mcimadamore@1415 154 for (ExceptionKind ek2 : ExceptionKind.values()) {
mcimadamore@1415 155 for (ArgTypeKind ak11 : ArgTypeKind.values()) {
mcimadamore@1415 156 for (ArgTypeKind ak12 : ArgTypeKind.values()) {
mcimadamore@1415 157 new StructuralMostSpecificTest(lrk, rk1, rk2, ek1, ek2, ak11, ak12).run(comp, fm);
mcimadamore@1415 158 }
mcimadamore@1415 159 }
mcimadamore@1415 160 }
mcimadamore@1415 161 }
mcimadamore@1415 162 }
mcimadamore@1415 163 }
mcimadamore@1415 164 }
mcimadamore@1415 165 System.out.println("Total check executed: " + checkCount);
mcimadamore@1415 166 }
mcimadamore@1415 167
mcimadamore@1415 168 LambdaReturnKind lrk;
mcimadamore@1415 169 RetTypeKind rt1, rt2;
mcimadamore@1415 170 ArgTypeKind ak1, ak2;
mcimadamore@1415 171 ExceptionKind ek1, ek2;
mcimadamore@1415 172 JavaSource source;
mcimadamore@1415 173 DiagnosticChecker diagChecker;
mcimadamore@1415 174
mcimadamore@1415 175 StructuralMostSpecificTest(LambdaReturnKind lrk, RetTypeKind rt1, RetTypeKind rt2,
mcimadamore@1415 176 ExceptionKind ek1, ExceptionKind ek2, ArgTypeKind ak1, ArgTypeKind ak2) {
mcimadamore@1415 177 this.lrk = lrk;
mcimadamore@1415 178 this.rt1 = rt1;
mcimadamore@1415 179 this.rt2 = rt2;
mcimadamore@1415 180 this.ek1 = ek1;
mcimadamore@1415 181 this.ek2 = ek2;
mcimadamore@1415 182 this.ak1 = ak1;
mcimadamore@1415 183 this.ak2 = ak2;
mcimadamore@1415 184 this.source = new JavaSource();
mcimadamore@1415 185 this.diagChecker = new DiagnosticChecker();
mcimadamore@1415 186 }
mcimadamore@1415 187
mcimadamore@1415 188 class JavaSource extends SimpleJavaFileObject {
mcimadamore@1415 189
mcimadamore@1415 190 String template = "interface SAM1 {\n" +
mcimadamore@1415 191 " #R1 m(#A1 a1) #E1;\n" +
mcimadamore@1415 192 "}\n" +
mcimadamore@1415 193 "interface SAM2 {\n" +
mcimadamore@1415 194 " #R2 m(#A2 a1) #E2;\n" +
mcimadamore@1415 195 "}\n" +
mcimadamore@1415 196 "class Test {\n" +
mcimadamore@1415 197 " void m(SAM1 s) { }\n" +
mcimadamore@1415 198 " void m(SAM2 s) { }\n" +
mcimadamore@1415 199 " { m(x->{ #LR }); }\n" +
mcimadamore@1415 200 "}\n";
mcimadamore@1415 201
mcimadamore@1415 202 String source;
mcimadamore@1415 203
mcimadamore@1415 204 public JavaSource() {
mcimadamore@1415 205 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
mcimadamore@1415 206 source = template.replaceAll("#LR", lrk.retStr)
mcimadamore@1415 207 .replaceAll("#R1", rt1.retTypeStr)
mcimadamore@1415 208 .replaceAll("#R2", rt2.retTypeStr)
mcimadamore@1415 209 .replaceAll("#A1", ak1.argTypeStr)
mcimadamore@1415 210 .replaceAll("#A2", ak2.argTypeStr)
mcimadamore@1415 211 .replaceAll("#E1", ek1.exceptionStr)
mcimadamore@1415 212 .replaceAll("#E2", ek2.exceptionStr);
mcimadamore@1415 213 }
mcimadamore@1415 214
mcimadamore@1415 215 @Override
mcimadamore@1415 216 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
mcimadamore@1415 217 return source;
mcimadamore@1415 218 }
mcimadamore@1415 219 }
mcimadamore@1415 220
mcimadamore@1415 221 void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
mcimadamore@1415 222 JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
mcimadamore@1415 223 Arrays.asList("-XDverboseResolution=all,-predef,-internal,-object-init"),
mcimadamore@1415 224 null, Arrays.asList(source));
mcimadamore@1415 225 try {
mcimadamore@1415 226 ct.analyze();
mcimadamore@1415 227 } catch (Throwable ex) {
mcimadamore@1415 228 throw new AssertionError("Error thron when analyzing the following source:\n" + source.getCharContent(true));
mcimadamore@1415 229 }
mcimadamore@1415 230 check();
mcimadamore@1415 231 }
mcimadamore@1415 232
mcimadamore@1415 233 void check() {
mcimadamore@1415 234 checkCount++;
mcimadamore@1415 235
mcimadamore@1415 236 if (!lrk.compatibleWith(rt1) || !lrk.compatibleWith(rt2))
mcimadamore@1415 237 return;
mcimadamore@1415 238
mcimadamore@1415 239 if (lrk.needsConversion(rt1) != lrk.needsConversion(rt2))
mcimadamore@1415 240 return;
mcimadamore@1415 241
mcimadamore@1415 242 boolean m1MoreSpecific = moreSpecific(rt1, rt2, ek1, ek2, ak1, ak2);
mcimadamore@1415 243 boolean m2MoreSpecific = moreSpecific(rt2, rt1, ek2, ek1, ak2, ak1);
mcimadamore@1415 244
mcimadamore@1415 245 boolean ambiguous = (m1MoreSpecific == m2MoreSpecific);
mcimadamore@1415 246
mcimadamore@1415 247 if (ambiguous != diagChecker.ambiguityFound) {
mcimadamore@1415 248 throw new Error("invalid diagnostics for source:\n" +
mcimadamore@1415 249 source.getCharContent(true) +
mcimadamore@1415 250 "\nAmbiguity found: " + diagChecker.ambiguityFound +
mcimadamore@1415 251 "\nm1 more specific: " + m1MoreSpecific +
mcimadamore@1415 252 "\nm2 more specific: " + m2MoreSpecific +
mcimadamore@1415 253 "\nexpected ambiguity: " + ambiguous);
mcimadamore@1415 254 }
mcimadamore@1415 255
mcimadamore@1415 256 if (!ambiguous) {
mcimadamore@1415 257 String sigToCheck = m1MoreSpecific ? "m(SAM1)" : "m(SAM2)";
mcimadamore@1415 258 if (!sigToCheck.equals(diagChecker.mostSpecificSig)) {
mcimadamore@1415 259 throw new Error("invalid most specific method selected:\n" +
mcimadamore@1415 260 source.getCharContent(true) +
mcimadamore@1415 261 "\nMost specific found: " + diagChecker.mostSpecificSig +
mcimadamore@1415 262 "\nm1 more specific: " + m1MoreSpecific +
mcimadamore@1415 263 "\nm2 more specific: " + m2MoreSpecific);
mcimadamore@1415 264 }
mcimadamore@1415 265 }
mcimadamore@1415 266 }
mcimadamore@1415 267
mcimadamore@1415 268 boolean moreSpecific(RetTypeKind rk1, RetTypeKind rk2, ExceptionKind ek1, ExceptionKind ek2,
mcimadamore@1415 269 ArgTypeKind ak1, ArgTypeKind ak2) {
mcimadamore@1415 270 if (!rk1.moreSpecificThan(rk2))
mcimadamore@1415 271 return false;
mcimadamore@1415 272
mcimadamore@1415 273 if (ak1 != ak2)
mcimadamore@1415 274 return false;
mcimadamore@1415 275
mcimadamore@1415 276 return true;
mcimadamore@1415 277 }
mcimadamore@1415 278
mcimadamore@1415 279 static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
mcimadamore@1415 280
mcimadamore@1415 281 boolean ambiguityFound;
mcimadamore@1415 282 String mostSpecificSig;
mcimadamore@1415 283
mcimadamore@1415 284 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
mcimadamore@1415 285 try {
mcimadamore@1415 286 if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
mcimadamore@1415 287 diagnostic.getCode().equals("compiler.err.ref.ambiguous")) {
mcimadamore@1415 288 ambiguityFound = true;
mcimadamore@1415 289 } else if (diagnostic.getKind() == Diagnostic.Kind.NOTE &&
mcimadamore@1415 290 diagnostic.getCode().equals("compiler.note.verbose.resolve.multi")) {
mcimadamore@1415 291 ClientCodeWrapper.DiagnosticSourceUnwrapper dsu =
mcimadamore@1415 292 (ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic;
mcimadamore@1415 293 JCDiagnostic.MultilineDiagnostic mdiag = (JCDiagnostic.MultilineDiagnostic)dsu.d;
mcimadamore@1415 294 int mostSpecificIndex = (Integer)mdiag.getArgs()[2];
mcimadamore@1415 295 mostSpecificSig = ((JCDiagnostic)mdiag.getSubdiagnostics().get(mostSpecificIndex)).getArgs()[1].toString();
mcimadamore@1415 296 }
mcimadamore@1415 297 } catch (RuntimeException t) {
mcimadamore@1415 298 t.printStackTrace();
mcimadamore@1415 299 throw t;
mcimadamore@1415 300 }
mcimadamore@1415 301 }
mcimadamore@1415 302 }
mcimadamore@1415 303 }

mercurial