1 /* 2 * Copyright (c) 2013, 2018, 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 8013576 8129962 27 * @summary Add stat support to LambdaToMethod 28 * @enablePreview 29 * @library /tools/javac/lib 30 * @modules jdk.compiler/com.sun.tools.javac.api 31 * jdk.compiler/com.sun.tools.javac.file 32 * jdk.compiler/com.sun.tools.javac.util 33 * @build combo.ComboTestHelper 34 * @run main TestLambdaToMethodStats 35 */ 36 37 import java.io.IOException; 38 39 import javax.tools.Diagnostic; 40 import javax.tools.JavaFileObject; 41 42 import com.sun.tools.javac.api.ClientCodeWrapper; 43 44 import com.sun.tools.javac.util.List; 45 import combo.ComboInstance; 46 import combo.ComboParameter; 47 import combo.ComboTask.Result; 48 import combo.ComboTestHelper; 49 50 public class TestLambdaToMethodStats extends ComboInstance<TestLambdaToMethodStats> { 51 52 enum ExprKind implements ComboParameter { 53 LAMBDA("()->null"), 54 MREF1("this::g"), 55 MREF2("this::h"); 56 57 String exprStr; 58 59 ExprKind(String exprStr) { 60 this.exprStr = exprStr; 61 } 62 63 @Override 64 public String expand(String optParameter) { 65 return exprStr; 66 } 67 } 68 69 enum TargetKind implements ComboParameter { 70 IMPLICIT(""), 71 SERIALIZABLE("(A & java.io.Serializable)"); 72 73 String targetStr; 74 75 TargetKind(String targetStr) { 76 this.targetStr = targetStr; 77 } 78 79 @Override 80 public String expand(String optParameter) { 81 return targetStr; 82 } 83 } 84 85 enum DiagnosticKind { 86 LAMBDA_STAT("compiler.note.lambda.stat", true, false), 87 MREF_STAT("compiler.note.mref.stat", false, false), 88 MREF_STAT1("compiler.note.mref.stat.1", false, true); 89 90 String code; 91 boolean lambda; 92 boolean bridge; 93 94 DiagnosticKind(String code, boolean lambda, boolean bridge) { 95 this.code = code; 96 this.lambda = lambda; 97 this.bridge = bridge; 98 } 99 } 100 101 public static void main(String... args) throws Exception { 102 new ComboTestHelper<TestLambdaToMethodStats>() 103 .withDimension("EXPR", (x, expr) -> x.ek = expr, ExprKind.values()) 104 .withDimension("CAST", (x, target) -> x.tk = target, TargetKind.values()) 105 .run(TestLambdaToMethodStats::new); 106 } 107 108 ExprKind ek; 109 TargetKind tk; 110 111 String template = "interface A {\n" + 112 " Object o();\n" + 113 "}\n" + 114 "class Test {\n" + 115 " A a = #{CAST}#{EXPR};\n" + 116 " Object g() { return null; }\n" + 117 " Object h(Object... o) { return null; }\n" + 118 "}"; 119 120 @Override 121 public void doWork() throws IOException { 122 newCompilationTask() 123 .withOption("--debug=dumpLambdaToMethodStats") 124 .withSourceFromTemplate(template) 125 .generate(this::check); 126 } 127 128 void check(Result<?> res) { 129 DiagnosticKind diag = null; 130 boolean altMetafactory = false; 131 for (DiagnosticKind dk : DiagnosticKind.values()) { 132 List<Diagnostic<? extends JavaFileObject>> jcDiag = res.diagnosticsForKey(dk.code); 133 if (jcDiag.nonEmpty()) { 134 diag = dk; 135 ClientCodeWrapper.DiagnosticSourceUnwrapper dsu = 136 (ClientCodeWrapper.DiagnosticSourceUnwrapper)jcDiag.head; 137 altMetafactory = (Boolean)dsu.d.getArgs()[0]; 138 break; 139 } 140 } 141 142 if (diag == null) { 143 fail("No diagnostic found; " + res.compilationInfo()); 144 } 145 146 boolean error = diag.lambda != 147 (ek == ExprKind.LAMBDA); 148 149 error |= diag.bridge != 150 (ek == ExprKind.MREF2); 151 152 error |= altMetafactory != 153 (tk == TargetKind.SERIALIZABLE); 154 155 if (error) { 156 fail("Bad stat diagnostic found for source\n" + 157 "lambda = " + diag.lambda + "\n" + 158 "bridge = " + diag.bridge + "\n" + 159 "altMF = " + altMetafactory + "\n" + 160 res.compilationInfo()); 161 } 162 } 163 }