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