test/tools/javac/lambda/LambdaParserTest.java

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2011, 2013, 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 7115050 8003280 8005852 8006694
aoqi@0 27 * @summary Add lambda tests
aoqi@0 28 * Add parser support for lambda expressions
aoqi@0 29 * temporarily workaround combo tests are causing time out in several platforms
aoqi@0 30 * @library ../lib
aoqi@0 31 * @build JavacTestingAbstractThreadedTest
aoqi@0 32 * @run main/othervm LambdaParserTest
aoqi@0 33 */
aoqi@0 34
aoqi@0 35 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
aoqi@0 36 // see JDK-8006746
aoqi@0 37
aoqi@0 38 import java.net.URI;
aoqi@0 39 import java.util.Arrays;
aoqi@0 40 import javax.tools.Diagnostic;
aoqi@0 41 import javax.tools.JavaFileObject;
aoqi@0 42 import javax.tools.SimpleJavaFileObject;
aoqi@0 43 import com.sun.source.util.JavacTask;
aoqi@0 44
aoqi@0 45 public class LambdaParserTest
aoqi@0 46 extends JavacTestingAbstractThreadedTest
aoqi@0 47 implements Runnable {
aoqi@0 48
aoqi@0 49 enum LambdaKind {
aoqi@0 50 NILARY_EXPR("()->x"),
aoqi@0 51 NILARY_STMT("()->{ return x; }"),
aoqi@0 52 ONEARY_SHORT_EXPR("#PN->x"),
aoqi@0 53 ONEARY_SHORT_STMT("#PN->{ return x; }"),
aoqi@0 54 ONEARY_EXPR("(#M1 #T1 #PN)->x"),
aoqi@0 55 ONEARY_STMT("(#M1 #T1 #PN)->{ return x; }"),
aoqi@0 56 TWOARY_EXPR("(#M1 #T1 #PN, #M2 #T2 y)->x"),
aoqi@0 57 TWOARY_STMT("(#M1 #T1 #PN, #M2 #T2 y)->{ return x; }");
aoqi@0 58
aoqi@0 59 String lambdaTemplate;
aoqi@0 60
aoqi@0 61 LambdaKind(String lambdaTemplate) {
aoqi@0 62 this.lambdaTemplate = lambdaTemplate;
aoqi@0 63 }
aoqi@0 64
aoqi@0 65 String getLambdaString(LambdaParameterKind pk1, LambdaParameterKind pk2,
aoqi@0 66 ModifierKind mk1, ModifierKind mk2, LambdaParameterName pn) {
aoqi@0 67 return lambdaTemplate.replaceAll("#M1", mk1.modifier)
aoqi@0 68 .replaceAll("#M2", mk2.modifier)
aoqi@0 69 .replaceAll("#T1", pk1.parameterType)
aoqi@0 70 .replaceAll("#T2", pk2.parameterType)
aoqi@0 71 .replaceAll("#PN", pn.nameStr);
aoqi@0 72 }
aoqi@0 73
aoqi@0 74 int arity() {
aoqi@0 75 switch (this) {
aoqi@0 76 case NILARY_EXPR:
aoqi@0 77 case NILARY_STMT: return 0;
aoqi@0 78 case ONEARY_SHORT_EXPR:
aoqi@0 79 case ONEARY_SHORT_STMT:
aoqi@0 80 case ONEARY_EXPR:
aoqi@0 81 case ONEARY_STMT: return 1;
aoqi@0 82 case TWOARY_EXPR:
aoqi@0 83 case TWOARY_STMT: return 2;
aoqi@0 84 default: throw new AssertionError("Invalid lambda kind " + this);
aoqi@0 85 }
aoqi@0 86 }
aoqi@0 87
aoqi@0 88 boolean isShort() {
aoqi@0 89 return this == ONEARY_SHORT_EXPR ||
aoqi@0 90 this == ONEARY_SHORT_STMT;
aoqi@0 91 }
aoqi@0 92 }
aoqi@0 93
aoqi@0 94 enum LambdaParameterName {
aoqi@0 95 IDENT("x"),
aoqi@0 96 UNDERSCORE("_");
aoqi@0 97
aoqi@0 98 String nameStr;
aoqi@0 99
aoqi@0 100 LambdaParameterName(String nameStr) {
aoqi@0 101 this.nameStr = nameStr;
aoqi@0 102 }
aoqi@0 103 }
aoqi@0 104
aoqi@0 105 enum LambdaParameterKind {
aoqi@0 106 IMPLICIT(""),
aoqi@0 107 EXPLIICT_SIMPLE("A"),
aoqi@0 108 EXPLIICT_SIMPLE_ARR1("A[]"),
aoqi@0 109 EXPLIICT_SIMPLE_ARR2("A[][]"),
aoqi@0 110 EXPLICIT_VARARGS("A..."),
aoqi@0 111 EXPLICIT_GENERIC1("A<X>"),
aoqi@0 112 EXPLICIT_GENERIC2("A<? extends X, ? super Y>"),
aoqi@0 113 EXPLICIT_GENERIC2_VARARGS("A<? extends X, ? super Y>..."),
aoqi@0 114 EXPLICIT_GENERIC2_ARR1("A<? extends X, ? super Y>[]"),
aoqi@0 115 EXPLICIT_GENERIC2_ARR2("A<? extends X, ? super Y>[][]");
aoqi@0 116
aoqi@0 117 String parameterType;
aoqi@0 118
aoqi@0 119 LambdaParameterKind(String parameterType) {
aoqi@0 120 this.parameterType = parameterType;
aoqi@0 121 }
aoqi@0 122
aoqi@0 123 boolean explicit() {
aoqi@0 124 return this != IMPLICIT;
aoqi@0 125 }
aoqi@0 126
aoqi@0 127 boolean isVarargs() {
aoqi@0 128 return this == EXPLICIT_VARARGS ||
aoqi@0 129 this == EXPLICIT_GENERIC2_VARARGS;
aoqi@0 130 }
aoqi@0 131 }
aoqi@0 132
aoqi@0 133 enum ModifierKind {
aoqi@0 134 NONE(""),
aoqi@0 135 FINAL("final"),
aoqi@0 136 PUBLIC("public");
aoqi@0 137
aoqi@0 138 String modifier;
aoqi@0 139
aoqi@0 140 ModifierKind(String modifier) {
aoqi@0 141 this.modifier = modifier;
aoqi@0 142 }
aoqi@0 143
aoqi@0 144 boolean compatibleWith(LambdaParameterKind pk) {
aoqi@0 145 switch (this) {
aoqi@0 146 case PUBLIC: return false;
aoqi@0 147 case FINAL: return pk != LambdaParameterKind.IMPLICIT;
aoqi@0 148 case NONE: return true;
aoqi@0 149 default: throw new AssertionError("Invalid modifier kind " + this);
aoqi@0 150 }
aoqi@0 151 }
aoqi@0 152 }
aoqi@0 153
aoqi@0 154 enum ExprKind {
aoqi@0 155 NONE("#L#S"),
aoqi@0 156 SINGLE_PAREN1("(#L#S)"),
aoqi@0 157 SINGLE_PAREN2("(#L)#S"),
aoqi@0 158 DOUBLE_PAREN1("((#L#S))"),
aoqi@0 159 DOUBLE_PAREN2("((#L)#S)"),
aoqi@0 160 DOUBLE_PAREN3("((#L))#S");
aoqi@0 161
aoqi@0 162 String expressionTemplate;
aoqi@0 163
aoqi@0 164 ExprKind(String expressionTemplate) {
aoqi@0 165 this.expressionTemplate = expressionTemplate;
aoqi@0 166 }
aoqi@0 167
aoqi@0 168 String expressionString(LambdaParameterKind pk1, LambdaParameterKind pk2,
aoqi@0 169 ModifierKind mk1, ModifierKind mk2, LambdaKind lk, LambdaParameterName pn, SubExprKind sk) {
aoqi@0 170 return expressionTemplate.replaceAll("#L", lk.getLambdaString(pk1, pk2, mk1, mk2, pn))
aoqi@0 171 .replaceAll("#S", sk.subExpression);
aoqi@0 172 }
aoqi@0 173 }
aoqi@0 174
aoqi@0 175 enum SubExprKind {
aoqi@0 176 NONE(""),
aoqi@0 177 SELECT_FIELD(".f"),
aoqi@0 178 SELECT_METHOD(".f()"),
aoqi@0 179 SELECT_NEW(".new Foo()"),
aoqi@0 180 POSTINC("++"),
aoqi@0 181 POSTDEC("--");
aoqi@0 182
aoqi@0 183 String subExpression;
aoqi@0 184
aoqi@0 185 SubExprKind(String subExpression) {
aoqi@0 186 this.subExpression = subExpression;
aoqi@0 187 }
aoqi@0 188 }
aoqi@0 189
aoqi@0 190 public static void main(String... args) throws Exception {
aoqi@0 191 for (LambdaKind lk : LambdaKind.values()) {
aoqi@0 192 for (LambdaParameterName pn : LambdaParameterName.values()) {
aoqi@0 193 for (LambdaParameterKind pk1 : LambdaParameterKind.values()) {
aoqi@0 194 if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT)
aoqi@0 195 continue;
aoqi@0 196 for (LambdaParameterKind pk2 : LambdaParameterKind.values()) {
aoqi@0 197 if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT)
aoqi@0 198 continue;
aoqi@0 199 for (ModifierKind mk1 : ModifierKind.values()) {
aoqi@0 200 if (mk1 != ModifierKind.NONE && lk.isShort())
aoqi@0 201 continue;
aoqi@0 202 if (lk.arity() < 1 && mk1 != ModifierKind.NONE)
aoqi@0 203 continue;
aoqi@0 204 for (ModifierKind mk2 : ModifierKind.values()) {
aoqi@0 205 if (lk.arity() < 2 && mk2 != ModifierKind.NONE)
aoqi@0 206 continue;
aoqi@0 207 for (SubExprKind sk : SubExprKind.values()) {
aoqi@0 208 for (ExprKind ek : ExprKind.values()) {
aoqi@0 209 pool.execute(
aoqi@0 210 new LambdaParserTest(pk1, pk2, mk1,
aoqi@0 211 mk2, lk, sk, ek, pn));
aoqi@0 212 }
aoqi@0 213 }
aoqi@0 214 }
aoqi@0 215 }
aoqi@0 216 }
aoqi@0 217 }
aoqi@0 218 }
aoqi@0 219 }
aoqi@0 220
aoqi@0 221 checkAfterExec();
aoqi@0 222 }
aoqi@0 223
aoqi@0 224 LambdaParameterKind pk1;
aoqi@0 225 LambdaParameterKind pk2;
aoqi@0 226 ModifierKind mk1;
aoqi@0 227 ModifierKind mk2;
aoqi@0 228 LambdaKind lk;
aoqi@0 229 LambdaParameterName pn;
aoqi@0 230 SubExprKind sk;
aoqi@0 231 ExprKind ek;
aoqi@0 232 JavaSource source;
aoqi@0 233 DiagnosticChecker diagChecker;
aoqi@0 234
aoqi@0 235 LambdaParserTest(LambdaParameterKind pk1, LambdaParameterKind pk2,
aoqi@0 236 ModifierKind mk1, ModifierKind mk2, LambdaKind lk,
aoqi@0 237 SubExprKind sk, ExprKind ek, LambdaParameterName pn) {
aoqi@0 238 this.pk1 = pk1;
aoqi@0 239 this.pk2 = pk2;
aoqi@0 240 this.mk1 = mk1;
aoqi@0 241 this.mk2 = mk2;
aoqi@0 242 this.lk = lk;
aoqi@0 243 this.pn = pn;
aoqi@0 244 this.sk = sk;
aoqi@0 245 this.ek = ek;
aoqi@0 246 this.source = new JavaSource();
aoqi@0 247 this.diagChecker = new DiagnosticChecker();
aoqi@0 248 }
aoqi@0 249
aoqi@0 250 class JavaSource extends SimpleJavaFileObject {
aoqi@0 251
aoqi@0 252 String template = "class Test {\n" +
aoqi@0 253 " SAM s = #E;\n" +
aoqi@0 254 "}";
aoqi@0 255
aoqi@0 256 String source;
aoqi@0 257
aoqi@0 258 public JavaSource() {
aoqi@0 259 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
aoqi@0 260 source = template.replaceAll("#E",
aoqi@0 261 ek.expressionString(pk1, pk2, mk1, mk2, lk, pn, sk));
aoqi@0 262 }
aoqi@0 263
aoqi@0 264 @Override
aoqi@0 265 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
aoqi@0 266 return source;
aoqi@0 267 }
aoqi@0 268 }
aoqi@0 269
aoqi@0 270 public void run() {
aoqi@0 271 JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
aoqi@0 272 null, null, Arrays.asList(source));
aoqi@0 273 try {
aoqi@0 274 ct.parse();
aoqi@0 275 } catch (Throwable ex) {
aoqi@0 276 processException(ex);
aoqi@0 277 return;
aoqi@0 278 }
aoqi@0 279 check();
aoqi@0 280 }
aoqi@0 281
aoqi@0 282 void check() {
aoqi@0 283 checkCount.incrementAndGet();
aoqi@0 284
aoqi@0 285 boolean errorExpected = (lk.arity() > 0 && !mk1.compatibleWith(pk1)) ||
aoqi@0 286 (lk.arity() > 1 && !mk2.compatibleWith(pk2));
aoqi@0 287
aoqi@0 288 if (lk.arity() == 2 &&
aoqi@0 289 (pk1.explicit() != pk2.explicit() ||
aoqi@0 290 pk1.isVarargs())) {
aoqi@0 291 errorExpected = true;
aoqi@0 292 }
aoqi@0 293
aoqi@0 294 errorExpected |= pn == LambdaParameterName.UNDERSCORE &&
aoqi@0 295 lk.arity() > 0;
aoqi@0 296
aoqi@0 297 if (errorExpected != diagChecker.errorFound) {
aoqi@0 298 throw new Error("invalid diagnostics for source:\n" +
aoqi@0 299 source.getCharContent(true) +
aoqi@0 300 "\nFound error: " + diagChecker.errorFound +
aoqi@0 301 "\nExpected error: " + errorExpected);
aoqi@0 302 }
aoqi@0 303 }
aoqi@0 304
aoqi@0 305 static class DiagnosticChecker
aoqi@0 306 implements javax.tools.DiagnosticListener<JavaFileObject> {
aoqi@0 307
aoqi@0 308 boolean errorFound;
aoqi@0 309
aoqi@0 310 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
aoqi@0 311 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
aoqi@0 312 errorFound = true;
aoqi@0 313 }
aoqi@0 314 }
aoqi@0 315 }
aoqi@0 316
aoqi@0 317 }

mercurial