test/tools/javac/lambda/MethodReferenceParserTest.java

Tue, 14 May 2013 11:11:09 -0700

author
rfield
date
Tue, 14 May 2013 11:11:09 -0700
changeset 1752
c09b7234cded
parent 1520
5c956be64b9e
child 1774
37295244f534
permissions
-rw-r--r--

8012556: Implement lambda methods on interfaces as static
8006140: Javac NPE compiling Lambda expression on initialization expression of static field in interface
Summary: Lambdas occurring in static contexts or those not needing instance information should be generated into static methods. This has long been the case for classes. However, as a work-around to the lack of support for statics on interfaces, interface lambda methods have been generated into default methods. For lambdas in interface static contexts (fields and static methods) this causes an NPE in javac because there is no 'this'. MethodHandles now support static methods on interfaces. This changeset allows lambda methods to be generated as static interface methods. An existing bug in Hotspot (8013875) is exposed in a test when the "-esa" flag is used. This test and another test that already exposed this bug have been marked with @ignore.
Reviewed-by: mcimadamore

mcimadamore@1145 1 /*
vromero@1482 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
mcimadamore@1145 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mcimadamore@1145 4 *
mcimadamore@1145 5 * This code is free software; you can redistribute it and/or modify it
mcimadamore@1145 6 * under the terms of the GNU General Public License version 2 only, as
mcimadamore@1145 7 * published by the Free Software Foundation.
mcimadamore@1145 8 *
mcimadamore@1145 9 * This code is distributed in the hope that it will be useful, but WITHOUT
mcimadamore@1145 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mcimadamore@1145 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mcimadamore@1145 12 * version 2 for more details (a copy is included in the LICENSE file that
mcimadamore@1145 13 * accompanied this code).
mcimadamore@1145 14 *
mcimadamore@1145 15 * You should have received a copy of the GNU General Public License version
mcimadamore@1145 16 * 2 along with this work; if not, write to the Free Software Foundation,
mcimadamore@1145 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mcimadamore@1145 18 *
mcimadamore@1145 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mcimadamore@1145 20 * or visit www.oracle.com if you need additional information or have any
mcimadamore@1145 21 * questions.
mcimadamore@1145 22 */
mcimadamore@1145 23
mcimadamore@1145 24 /*
mcimadamore@1145 25 * @test
mcimadamore@1145 26 * @bug 7115052
vromero@1520 27 * @bug 8003280 8006694
mcimadamore@1415 28 * @summary Add lambda tests
mcimadamore@1415 29 * Add parser support for method references
vromero@1520 30 * temporarily workaround combo tests are causing time out in several platforms
vromero@1482 31 * @library ../lib
vromero@1482 32 * @build JavacTestingAbstractThreadedTest
vromero@1520 33 * @run main/othervm MethodReferenceParserTest
mcimadamore@1145 34 */
mcimadamore@1145 35
vromero@1520 36 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
vromero@1520 37 // see JDK-8006746
vromero@1520 38
mcimadamore@1145 39 import java.net.URI;
mcimadamore@1145 40 import java.util.Arrays;
mcimadamore@1145 41 import javax.tools.Diagnostic;
mcimadamore@1145 42 import javax.tools.JavaFileObject;
mcimadamore@1145 43 import javax.tools.SimpleJavaFileObject;
vromero@1482 44 import com.sun.source.util.JavacTask;
mcimadamore@1145 45
vromero@1482 46 public class MethodReferenceParserTest
vromero@1482 47 extends JavacTestingAbstractThreadedTest
vromero@1482 48 implements Runnable {
mcimadamore@1145 49
mcimadamore@1145 50 enum ReferenceKind {
mcimadamore@1352 51 METHOD_REF("#Q::#Gm"),
mcimadamore@1352 52 CONSTRUCTOR_REF("#Q::#Gnew"),
mcimadamore@1165 53 FALSE_REF("min < max"),
mcimadamore@1352 54 ERR_SUPER("#Q::#Gsuper"),
mcimadamore@1352 55 ERR_METH0("#Q::#Gm()"),
mcimadamore@1352 56 ERR_METH1("#Q::#Gm(X)"),
mcimadamore@1352 57 ERR_CONSTR0("#Q::#Gnew()"),
mcimadamore@1352 58 ERR_CONSTR1("#Q::#Gnew(X)");
mcimadamore@1145 59
mcimadamore@1145 60 String referenceTemplate;
mcimadamore@1145 61
mcimadamore@1145 62 ReferenceKind(String referenceTemplate) {
mcimadamore@1145 63 this.referenceTemplate = referenceTemplate;
mcimadamore@1145 64 }
mcimadamore@1145 65
mcimadamore@1145 66 String getReferenceString(QualifierKind qk, GenericKind gk) {
mcimadamore@1145 67 return referenceTemplate
mcimadamore@1145 68 .replaceAll("#Q", qk.qualifier)
mcimadamore@1145 69 .replaceAll("#G", gk.typeParameters);
mcimadamore@1145 70 }
mcimadamore@1145 71
mcimadamore@1145 72 boolean erroneous() {
mcimadamore@1145 73 switch (this) {
mcimadamore@1145 74 case ERR_SUPER:
mcimadamore@1145 75 case ERR_METH0:
mcimadamore@1145 76 case ERR_METH1:
mcimadamore@1145 77 case ERR_CONSTR0:
mcimadamore@1145 78 case ERR_CONSTR1:
mcimadamore@1145 79 return true;
mcimadamore@1145 80 default: return false;
mcimadamore@1145 81 }
mcimadamore@1145 82 }
mcimadamore@1145 83 }
mcimadamore@1145 84
mcimadamore@1165 85 enum ContextKind {
mcimadamore@1165 86 ASSIGN("SAM s = #E;"),
mcimadamore@1165 87 METHOD("m(#E, i);");
mcimadamore@1165 88
mcimadamore@1165 89 String contextTemplate;
mcimadamore@1165 90
mcimadamore@1165 91 ContextKind(String contextTemplate) {
mcimadamore@1165 92 this.contextTemplate = contextTemplate;
mcimadamore@1165 93 }
mcimadamore@1165 94
vromero@1482 95 String contextString(ExprKind ek, ReferenceKind rk, QualifierKind qk,
vromero@1482 96 GenericKind gk, SubExprKind sk) {
mcimadamore@1165 97 return contextTemplate.replaceAll("#E", ek.expressionString(rk, qk, gk, sk));
mcimadamore@1165 98 }
mcimadamore@1165 99 }
mcimadamore@1165 100
mcimadamore@1145 101 enum GenericKind {
mcimadamore@1145 102 NONE(""),
mcimadamore@1145 103 ONE("<X>"),
mcimadamore@1145 104 TWO("<X,Y>");
mcimadamore@1145 105
mcimadamore@1145 106 String typeParameters;
mcimadamore@1145 107
mcimadamore@1145 108 GenericKind(String typeParameters) {
mcimadamore@1145 109 this.typeParameters = typeParameters;
mcimadamore@1145 110 }
mcimadamore@1145 111 }
mcimadamore@1145 112
mcimadamore@1145 113 enum QualifierKind {
mcimadamore@1145 114 THIS("this"),
mcimadamore@1145 115 SUPER("super"),
mcimadamore@1145 116 NEW("new Foo()"),
mcimadamore@1145 117 METHOD("m()"),
mcimadamore@1145 118 FIELD("a.f"),
mcimadamore@1145 119 UBOUND_SIMPLE("A"),
mcimadamore@1352 120 UNBOUND_ARRAY1("int[]"),
mcimadamore@1352 121 UNBOUND_ARRAY2("A<G>[][]"),
mcimadamore@1145 122 UNBOUND_GENERIC1("A<X>"),
mcimadamore@1145 123 UNBOUND_GENERIC2("A<X, Y>"),
mcimadamore@1165 124 UNBOUND_GENERIC3("A<? extends X, ? super Y>"),
mcimadamore@1165 125 UNBOUND_GENERIC4("A<int[], short[][]>"),
mcimadamore@1165 126 NESTED_GENERIC1("A<A<X,Y>, A<X,Y>>"),
mcimadamore@1165 127 NESTED_GENERIC2("A<A<A<X,Y>,A<X,Y>>, A<A<X,Y>,A<X,Y>>>");
mcimadamore@1145 128
mcimadamore@1145 129 String qualifier;
mcimadamore@1145 130
mcimadamore@1145 131 QualifierKind(String qualifier) {
mcimadamore@1145 132 this.qualifier = qualifier;
mcimadamore@1145 133 }
mcimadamore@1145 134 }
mcimadamore@1145 135
mcimadamore@1145 136 enum ExprKind {
mcimadamore@1352 137 NONE("#R::S"),
mcimadamore@1145 138 SINGLE_PAREN1("(#R#S)"),
mcimadamore@1145 139 SINGLE_PAREN2("(#R)#S"),
mcimadamore@1145 140 DOUBLE_PAREN1("((#R#S))"),
mcimadamore@1145 141 DOUBLE_PAREN2("((#R)#S)"),
mcimadamore@1145 142 DOUBLE_PAREN3("((#R))#S");
mcimadamore@1145 143
mcimadamore@1145 144 String expressionTemplate;
mcimadamore@1145 145
mcimadamore@1145 146 ExprKind(String expressionTemplate) {
mcimadamore@1145 147 this.expressionTemplate = expressionTemplate;
mcimadamore@1145 148 }
mcimadamore@1145 149
mcimadamore@1145 150 String expressionString(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk) {
mcimadamore@1145 151 return expressionTemplate
mcimadamore@1145 152 .replaceAll("#R", rk.getReferenceString(qk, gk))
mcimadamore@1145 153 .replaceAll("#S", sk.subExpression);
mcimadamore@1145 154 }
mcimadamore@1145 155 }
mcimadamore@1145 156
mcimadamore@1145 157 enum SubExprKind {
mcimadamore@1145 158 NONE(""),
mcimadamore@1145 159 SELECT_FIELD(".f"),
mcimadamore@1145 160 SELECT_METHOD(".f()"),
mcimadamore@1145 161 SELECT_NEW(".new Foo()"),
mcimadamore@1145 162 POSTINC("++"),
mcimadamore@1145 163 POSTDEC("--");
mcimadamore@1145 164
mcimadamore@1145 165 String subExpression;
mcimadamore@1145 166
mcimadamore@1145 167 SubExprKind(String subExpression) {
mcimadamore@1145 168 this.subExpression = subExpression;
mcimadamore@1145 169 }
mcimadamore@1145 170 }
mcimadamore@1145 171
mcimadamore@1145 172 public static void main(String... args) throws Exception {
mcimadamore@1145 173 for (ReferenceKind rk : ReferenceKind.values()) {
mcimadamore@1145 174 for (QualifierKind qk : QualifierKind.values()) {
mcimadamore@1145 175 for (GenericKind gk : GenericKind.values()) {
mcimadamore@1145 176 for (SubExprKind sk : SubExprKind.values()) {
mcimadamore@1145 177 for (ExprKind ek : ExprKind.values()) {
mcimadamore@1165 178 for (ContextKind ck : ContextKind.values()) {
vromero@1482 179 pool.execute(new MethodReferenceParserTest(rk, qk, gk, sk, ek, ck));
mcimadamore@1165 180 }
mcimadamore@1145 181 }
mcimadamore@1145 182 }
mcimadamore@1145 183 }
mcimadamore@1145 184 }
mcimadamore@1145 185 }
vromero@1482 186
vromero@1482 187 checkAfterExec();
mcimadamore@1145 188 }
mcimadamore@1145 189
mcimadamore@1145 190 ReferenceKind rk;
mcimadamore@1145 191 QualifierKind qk;
mcimadamore@1145 192 GenericKind gk;
mcimadamore@1145 193 SubExprKind sk;
mcimadamore@1145 194 ExprKind ek;
mcimadamore@1165 195 ContextKind ck;
mcimadamore@1145 196 JavaSource source;
mcimadamore@1145 197 DiagnosticChecker diagChecker;
mcimadamore@1145 198
mcimadamore@1165 199 MethodReferenceParserTest(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk, ExprKind ek, ContextKind ck) {
mcimadamore@1145 200 this.rk = rk;
mcimadamore@1145 201 this.qk = qk;
mcimadamore@1145 202 this.gk = gk;
mcimadamore@1145 203 this.sk = sk;
mcimadamore@1145 204 this.ek = ek;
mcimadamore@1165 205 this.ck = ck;
mcimadamore@1145 206 this.source = new JavaSource();
mcimadamore@1145 207 this.diagChecker = new DiagnosticChecker();
mcimadamore@1145 208 }
mcimadamore@1145 209
mcimadamore@1145 210 class JavaSource extends SimpleJavaFileObject {
mcimadamore@1145 211
mcimadamore@1145 212 String template = "class Test {\n" +
mcimadamore@1165 213 " void test() {\n" +
mcimadamore@1165 214 " #C\n" +
mcimadamore@1165 215 " }" +
mcimadamore@1145 216 "}";
mcimadamore@1145 217
mcimadamore@1145 218 String source;
mcimadamore@1145 219
mcimadamore@1145 220 public JavaSource() {
mcimadamore@1145 221 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
mcimadamore@1165 222 source = template.replaceAll("#C", ck.contextString(ek, rk, qk, gk, sk));
mcimadamore@1145 223 }
mcimadamore@1145 224
mcimadamore@1145 225 @Override
mcimadamore@1145 226 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
mcimadamore@1145 227 return source;
mcimadamore@1145 228 }
mcimadamore@1145 229 }
mcimadamore@1145 230
vromero@1482 231 @Override
vromero@1482 232 public void run() {
vromero@1482 233 JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
mcimadamore@1415 234 null, null, Arrays.asList(source));
mcimadamore@1145 235 try {
mcimadamore@1145 236 ct.parse();
mcimadamore@1145 237 } catch (Throwable ex) {
vromero@1482 238 processException(ex);
vromero@1482 239 return;
mcimadamore@1145 240 }
mcimadamore@1145 241 check();
mcimadamore@1145 242 }
mcimadamore@1145 243
mcimadamore@1145 244 void check() {
vromero@1482 245 checkCount.incrementAndGet();
mcimadamore@1145 246
mcimadamore@1145 247 if (diagChecker.errorFound != rk.erroneous()) {
mcimadamore@1145 248 throw new Error("invalid diagnostics for source:\n" +
mcimadamore@1145 249 source.getCharContent(true) +
mcimadamore@1145 250 "\nFound error: " + diagChecker.errorFound +
mcimadamore@1145 251 "\nExpected error: " + rk.erroneous());
mcimadamore@1145 252 }
mcimadamore@1145 253 }
mcimadamore@1145 254
mcimadamore@1145 255 static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
mcimadamore@1145 256
mcimadamore@1145 257 boolean errorFound;
mcimadamore@1145 258
mcimadamore@1145 259 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
mcimadamore@1145 260 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
mcimadamore@1145 261 errorFound = true;
mcimadamore@1145 262 }
mcimadamore@1145 263 }
mcimadamore@1145 264 }
vromero@1482 265
mcimadamore@1145 266 }

mercurial