diff -r 000000000000 -r 959103a6100f test/tools/javac/lambda/MethodReferenceParserTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/MethodReferenceParserTest.java Wed Apr 27 01:34:52 2016 +0800 @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7115052 8003280 8006694 + * @summary Add lambda tests + * Add parser support for method references + * temporarily workaround combo tests are causing time out in several platforms + * @library ../lib + * @build JavacTestingAbstractThreadedTest + * @run main/othervm MethodReferenceParserTest + */ + +// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047) +// see JDK-8006746 + +import java.net.URI; +import java.util.Arrays; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import com.sun.source.util.JavacTask; + +public class MethodReferenceParserTest + extends JavacTestingAbstractThreadedTest + implements Runnable { + + enum ReferenceKind { + METHOD_REF("#Q::#Gm"), + CONSTRUCTOR_REF("#Q::#Gnew"), + FALSE_REF("min < max"), + ERR_SUPER("#Q::#Gsuper"), + ERR_METH0("#Q::#Gm()"), + ERR_METH1("#Q::#Gm(X)"), + ERR_CONSTR0("#Q::#Gnew()"), + ERR_CONSTR1("#Q::#Gnew(X)"); + + String referenceTemplate; + + ReferenceKind(String referenceTemplate) { + this.referenceTemplate = referenceTemplate; + } + + String getReferenceString(QualifierKind qk, GenericKind gk) { + return referenceTemplate + .replaceAll("#Q", qk.qualifier) + .replaceAll("#G", gk.typeParameters); + } + + boolean erroneous() { + switch (this) { + case ERR_SUPER: + case ERR_METH0: + case ERR_METH1: + case ERR_CONSTR0: + case ERR_CONSTR1: + return true; + default: return false; + } + } + } + + enum ContextKind { + ASSIGN("SAM s = #E;"), + METHOD("m(#E, i);"); + + String contextTemplate; + + ContextKind(String contextTemplate) { + this.contextTemplate = contextTemplate; + } + + String contextString(ExprKind ek, ReferenceKind rk, QualifierKind qk, + GenericKind gk, SubExprKind sk) { + return contextTemplate.replaceAll("#E", ek.expressionString(rk, qk, gk, sk)); + } + } + + enum GenericKind { + NONE(""), + ONE(""), + TWO(""); + + String typeParameters; + + GenericKind(String typeParameters) { + this.typeParameters = typeParameters; + } + } + + enum QualifierKind { + THIS("this"), + SUPER("super"), + NEW("new Foo()"), + METHOD("m()"), + FIELD("a.f"), + UBOUND_SIMPLE("A"), + UNBOUND_ARRAY1("int[]"), + UNBOUND_ARRAY2("A[][]"), + UNBOUND_GENERIC1("A"), + UNBOUND_GENERIC2("A"), + UNBOUND_GENERIC3("A"), + UNBOUND_GENERIC4("A"), + NESTED_GENERIC1("A, A>"), + NESTED_GENERIC2("A,A>, A,A>>"); + + String qualifier; + + QualifierKind(String qualifier) { + this.qualifier = qualifier; + } + } + + enum ExprKind { + NONE("#R::S"), + SINGLE_PAREN1("(#R#S)"), + SINGLE_PAREN2("(#R)#S"), + DOUBLE_PAREN1("((#R#S))"), + DOUBLE_PAREN2("((#R)#S)"), + DOUBLE_PAREN3("((#R))#S"); + + String expressionTemplate; + + ExprKind(String expressionTemplate) { + this.expressionTemplate = expressionTemplate; + } + + String expressionString(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk) { + return expressionTemplate + .replaceAll("#R", rk.getReferenceString(qk, gk)) + .replaceAll("#S", sk.subExpression); + } + } + + enum SubExprKind { + NONE(""), + SELECT_FIELD(".f"), + SELECT_METHOD(".f()"), + SELECT_NEW(".new Foo()"), + POSTINC("++"), + POSTDEC("--"); + + String subExpression; + + SubExprKind(String subExpression) { + this.subExpression = subExpression; + } + } + + public static void main(String... args) throws Exception { + for (ReferenceKind rk : ReferenceKind.values()) { + for (QualifierKind qk : QualifierKind.values()) { + for (GenericKind gk : GenericKind.values()) { + for (SubExprKind sk : SubExprKind.values()) { + for (ExprKind ek : ExprKind.values()) { + for (ContextKind ck : ContextKind.values()) { + pool.execute(new MethodReferenceParserTest(rk, qk, gk, sk, ek, ck)); + } + } + } + } + } + } + + checkAfterExec(); + } + + ReferenceKind rk; + QualifierKind qk; + GenericKind gk; + SubExprKind sk; + ExprKind ek; + ContextKind ck; + JavaSource source; + DiagnosticChecker diagChecker; + + MethodReferenceParserTest(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk, ExprKind ek, ContextKind ck) { + this.rk = rk; + this.qk = qk; + this.gk = gk; + this.sk = sk; + this.ek = ek; + this.ck = ck; + this.source = new JavaSource(); + this.diagChecker = new DiagnosticChecker(); + } + + class JavaSource extends SimpleJavaFileObject { + + String template = "class Test {\n" + + " void test() {\n" + + " #C\n" + + " }" + + "}"; + + String source; + + public JavaSource() { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + source = template.replaceAll("#C", ck.contextString(ek, rk, qk, gk, sk)); + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return source; + } + } + + @Override + public void run() { + JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker, + null, null, Arrays.asList(source)); + try { + ct.parse(); + } catch (Throwable ex) { + processException(ex); + return; + } + check(); + } + + void check() { + checkCount.incrementAndGet(); + + if (diagChecker.errorFound != rk.erroneous()) { + throw new Error("invalid diagnostics for source:\n" + + source.getCharContent(true) + + "\nFound error: " + diagChecker.errorFound + + "\nExpected error: " + rk.erroneous()); + } + } + + static class DiagnosticChecker implements javax.tools.DiagnosticListener { + + boolean errorFound; + + public void report(Diagnostic diagnostic) { + if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { + errorFound = true; + } + } + } + +}