1/* 2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* 25 * @test 26 * @bug 8003280 27 * @summary Add lambda tests 28 * compile crashes on partial lambda expressions 29 * @modules jdk.compiler 30 */ 31 32import com.sun.source.util.JavacTask; 33import java.net.URI; 34import java.util.Arrays; 35import javax.tools.Diagnostic; 36import javax.tools.JavaCompiler; 37import javax.tools.JavaFileObject; 38import javax.tools.SimpleJavaFileObject; 39import javax.tools.StandardJavaFileManager; 40import javax.tools.ToolProvider; 41 42 43public class BadLambdaExpr { 44 45 static int checkCount = 0; 46 47 enum ParameterListKind { 48 ZERO_ARY("()"), 49 UNARY("(#P)"), 50 TWO_ARY("(#P, #P)"), 51 THREE_ARY("(#P, #P, #P)"); 52 53 String parametersTemplateStr; 54 55 ParameterListKind(String parametersTemplateStr) { 56 this.parametersTemplateStr = parametersTemplateStr; 57 } 58 59 String getParameterString(ParameterKind pk) { 60 return parametersTemplateStr.replaceAll("#P", pk.parameterStr); 61 } 62 } 63 64 enum ParameterKind { 65 IMPLICIT("a"), 66 EXPLIICT("A a"); 67 68 String parameterStr; 69 70 ParameterKind(String parameterStr) { 71 this.parameterStr = parameterStr; 72 } 73 } 74 75 enum ArrowKind { 76 NONE(""), 77 SEMI("-"), 78 FULL("->"); 79 80 String arrowStr; 81 82 ArrowKind(String arrowStr) { 83 this.arrowStr = arrowStr; 84 } 85 } 86 87 enum ExprKind { 88 NONE("#P#A"), 89 METHOD_CALL("m(#P#A)"), 90 CONSTR_CALL("new Foo(#P#A)"); 91 92 String expressionTemplate; 93 94 ExprKind(String expressionTemplate) { 95 this.expressionTemplate = expressionTemplate; 96 } 97 98 String expressionString(ParameterListKind plk, ParameterKind pk, 99 ArrowKind ak) { 100 return expressionTemplate.replaceAll("#P", plk.getParameterString(pk)) 101 .replaceAll("#A", ak.arrowStr); 102 } 103 } 104 105 public static void main(String... args) throws Exception { 106 107 //create default shared JavaCompiler - reused across multiple compilations 108 JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); 109 try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { 110 111 for (ParameterListKind plk : ParameterListKind.values()) { 112 for (ParameterKind pk : ParameterKind.values()) { 113 for (ArrowKind ak : ArrowKind.values()) { 114 for (ExprKind ek : ExprKind.values()) { 115 new BadLambdaExpr(plk, pk, ak, ek).run(comp, fm); 116 } 117 } 118 } 119 } 120 System.out.println("Total check executed: " + checkCount); 121 } 122 } 123 124 ParameterListKind plk; 125 ParameterKind pk; 126 ArrowKind ak; 127 ExprKind ek; 128 JavaSource source; 129 DiagnosticChecker diagChecker; 130 131 BadLambdaExpr(ParameterListKind plk, ParameterKind pk, ArrowKind ak, ExprKind ek) { 132 this.plk = plk; 133 this.pk = pk; 134 this.ak = ak; 135 this.ek = ek; 136 this.source = new JavaSource(); 137 this.diagChecker = new DiagnosticChecker(); 138 } 139 140 class JavaSource extends SimpleJavaFileObject { 141 142 String template = "class Test {\n" + 143 " SAM s = #E;\n" + 144 "}"; 145 146 String source; 147 148 public JavaSource() { 149 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 150 source = template.replaceAll("#E", ek.expressionString(plk, pk, ak)); 151 } 152 153 @Override 154 public CharSequence getCharContent(boolean ignoreEncodingErrors) { 155 return source; 156 } 157 } 158 159 void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception { 160 JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker, 161 null, null, Arrays.asList(source)); 162 try { 163 ct.parse(); 164 } catch (Throwable ex) { 165 throw new AssertionError("Error thron when parsing the following source:\n" + source.getCharContent(true)); 166 } 167 check(); 168 } 169 170 void check() { 171 boolean errorExpected = 172 ak != ArrowKind.NONE || 173 plk != ParameterListKind.UNARY || 174 pk != ParameterKind.IMPLICIT; 175 if (errorExpected != diagChecker.errorFound) { 176 throw new Error("bad diag for source:\n" + 177 source.getCharContent(true)); 178 } 179 checkCount++; 180 } 181 182 static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> { 183 184 boolean errorFound; 185 186 @Override 187 public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 188 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { 189 errorFound = true; 190 } 191 } 192 } 193} 194