TestUncheckedCalls.java revision 4057:0025bb118860
155682Smarkm/* 2233294Sstas * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3233294Sstas * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4233294Sstas * 555682Smarkm * This code is free software; you can redistribute it and/or modify it 6233294Sstas * under the terms of the GNU General Public License version 2 only, as 7233294Sstas * published by the Free Software Foundation. Oracle designates this 8233294Sstas * particular file as subject to the "Classpath" exception as provided 955682Smarkm * by Oracle in the LICENSE file that accompanied this code. 10233294Sstas * 11233294Sstas * This code is distributed in the hope that it will be useful, but WITHOUT 1255682Smarkm * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13233294Sstas * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14233294Sstas * version 2 for more details (a copy is included in the LICENSE file that 15233294Sstas * accompanied this code). 1655682Smarkm * 17233294Sstas * You should have received a copy of the GNU General Public License version 18233294Sstas * 2 along with this work; if not, write to the Free Software Foundation, 19233294Sstas * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2055682Smarkm * 21233294Sstas * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22233294Sstas * or visit www.oracle.com if you need additional information or have any 23233294Sstas * questions. 24233294Sstas */ 25233294Sstas 26233294Sstasimport combo.ComboInstance; 27233294Sstasimport combo.ComboParameter; 28233294Sstasimport combo.ComboTask.Result; 29233294Sstasimport combo.ComboTestHelper; 30233294Sstas 31233294Sstasimport javax.lang.model.element.Element; 3255682Smarkmimport java.util.stream.Stream; 3355682Smarkm 3455682Smarkm/* 35102644Snectar * @test 3655682Smarkm * @bug 8176534 3772445Sassar * @summary Missing check against target-type during applicability inference 3872445Sassar * @library /tools/javac/lib 39178825Sdfr * @modules jdk.compiler/com.sun.tools.javac.api 40178825Sdfr * jdk.compiler/com.sun.tools.javac.code 41178825Sdfr * jdk.compiler/com.sun.tools.javac.comp 42120945Snectar * jdk.compiler/com.sun.tools.javac.main 43178825Sdfr * jdk.compiler/com.sun.tools.javac.tree 44178825Sdfr * jdk.compiler/com.sun.tools.javac.util 45178825Sdfr * @build combo.ComboTestHelper 46178825Sdfr * 47178825Sdfr * @run main TestUncheckedCalls 48233294Sstas */ 4955682Smarkmpublic class TestUncheckedCalls extends ComboInstance<TestUncheckedCalls> { 5055682Smarkm enum InputExpressionKind implements ComboParameter { 51233294Sstas A("(A)null"), 5255682Smarkm A_STRING("(A<String>)null"), 53178825Sdfr B("(B)null"), 54233294Sstas B_STRING("(B<String>)null"); 5555682Smarkm 56178825Sdfr String inputExpr; 57178825Sdfr 5855682Smarkm InputExpressionKind(String inputExpr) { 5955682Smarkm this.inputExpr = inputExpr; 6055682Smarkm } 6155682Smarkm 6255682Smarkm 63178825Sdfr @Override 6455682Smarkm public String expand(String optParameter) { 6555682Smarkm return inputExpr; 6655682Smarkm } 6755682Smarkm } 68233294Sstas 69233294Sstas enum TypeKind implements ComboParameter { 70233294Sstas Z("Z"), 71233294Sstas C_T("#C<T>"), 72233294Sstas C_STRING("#C<String>"), 73233294Sstas C("#C"); 74233294Sstas 75233294Sstas String typeTemplate; 76233294Sstas 77233294Sstas TypeKind(String typeTemplate) { 78233294Sstas this.typeTemplate = typeTemplate; 79233294Sstas } 80233294Sstas 81233294Sstas boolean hasTypeVars() { 8255682Smarkm return this == Z || this == C_T; 8355682Smarkm } 84233294Sstas 85178825Sdfr @Override 8655682Smarkm public String expand(String className) { 87233294Sstas return typeTemplate.replaceAll("#C", className); 8855682Smarkm } 8955682Smarkm } 9055682Smarkm 9155682Smarkm enum TypeVarsKind implements ComboParameter { 92233294Sstas NONE("", "Object"), 93233294Sstas Z_T("<Z extends #C<T>, T>", "Z"); 9490926Snectar 9555682Smarkm String typeVarsTemplate; 9655682Smarkm String paramString; 97178825Sdfr 98178825Sdfr TypeVarsKind(String typeVarsTemplate, String paramString) { 99178825Sdfr this.typeVarsTemplate = typeVarsTemplate; 100233294Sstas this.paramString = paramString; 101178825Sdfr } 102178825Sdfr 103178825Sdfr 104178825Sdfr @Override 105178825Sdfr public String expand(String className) { 106178825Sdfr if (className.equals("Z")) { 107178825Sdfr return paramString; 108178825Sdfr } else { 109178825Sdfr return typeVarsTemplate.replaceAll("#C", className); 110178825Sdfr } 111178825Sdfr } 112233294Sstas } 113178825Sdfr 114178825Sdfr enum CallKind implements ComboParameter { 11555682Smarkm M("M(#{IN}, #{IN})"), 11655682Smarkm M_G("M(G(#{IN}, #{IN}), #{IN})"), 11755682Smarkm M_G_G("M(G(#{IN}, #{IN}), G(#{IN}, #{IN}))"); 11855682Smarkm 11955682Smarkm String callExpr; 12055682Smarkm 12155682Smarkm CallKind(String callExpr) { 122250782Sbz this.callExpr = callExpr; 123250782Sbz } 124250782Sbz 125250782Sbz 126250782Sbz @Override 127250782Sbz public String expand(String optParameter) { 128250782Sbz return callExpr; 129250782Sbz } 130250782Sbz } 131250782Sbz 132250782Sbz enum DeclKind implements ComboParameter { 133250782Sbz NONE(""), 134250782Sbz ONE("#{TVARS[#M_IDX].I1} #{RET[#M_IDX].A} #M(#{ARG[#M_IDX].A} x1, #{TVARS[#M_IDX].Z} x2) { return null; }"), 135250782Sbz TWO("#{TVARS[#M_IDX].I1} #{RET[#M_IDX].A} #M(#{ARG[#M_IDX].A} x1, #{TVARS[#M_IDX].Z} x2) { return null; }\n" + 136250782Sbz " #{TVARS[#M_IDX].I2} #{RET[#M_IDX].B} #M(#{ARG[#M_IDX].B} x1, #{TVARS[#M_IDX].Z} x2) { return null; }"); 137250782Sbz 138250782Sbz String declTemplate; 139250782Sbz 140250782Sbz DeclKind(String declTemplate) { 141250782Sbz this.declTemplate = declTemplate; 142250782Sbz } 143250782Sbz 144250782Sbz @Override 145250782Sbz public String expand(String methName) { 146250782Sbz return declTemplate.replaceAll("#M_IDX", methName.equals("M") ? "0" : "1") 147250782Sbz .replaceAll("#M", methName); 148250782Sbz 149250782Sbz } 150250782Sbz } 151250782Sbz 152250782Sbz static final String sourceTemplate = 153250782Sbz "class Test {\n" + 154250782Sbz " interface I1<X> { }\n" + 155250782Sbz " interface I2<X> { }\n" + 156250782Sbz " static class A<X> implements I1<X> { }\n" + 157250782Sbz " static class B<X> implements I2<X> { }\n" + 158250782Sbz " #{DECL[0].M}\n" + 159250782Sbz " #{DECL[1].G}\n" + 160250782Sbz " void test() {\n" + 161250782Sbz " #{CALL};\n" + 162250782Sbz " }\n" + 163250782Sbz "}\n"; 164250782Sbz 165250782Sbz public static void main(String... args) throws Exception { 166250782Sbz new ComboTestHelper<TestUncheckedCalls>() 167250782Sbz .withFilter(TestUncheckedCalls::arityFilter) 168250782Sbz .withFilter(TestUncheckedCalls::declFilter) 16955682Smarkm .withFilter(TestUncheckedCalls::tvarFilter) 170233294Sstas .withFilter(TestUncheckedCalls::inputExprFilter) 171250782Sbz .withDimension("IN", (x, expr) -> x.inputExpressionKind = expr, InputExpressionKind.values()) 17255682Smarkm .withDimension("CALL", (x, expr) -> x.callKind = expr, CallKind.values()) 17355682Smarkm .withArrayDimension("DECL", (x, decl, idx) -> x.decls[idx] = x.new Decl(decl, idx), 2, DeclKind.values()) 174178825Sdfr .withArrayDimension("TVARS", (x, tvars, idx) -> x.typeVarsKinds[idx] = tvars, 2, TypeVarsKind.values()) 175102644Snectar .withArrayDimension("RET", (x, ret, idx) -> x.returnKinds[idx] = ret, 2, TypeKind.values()) 176102644Snectar .withArrayDimension("ARG", (x, arg, idx) -> x.argumentKinds[idx] = arg, 2, TypeKind.values()) 177102644Snectar .run(TestUncheckedCalls::new); 178178825Sdfr } 17955682Smarkm 18055682Smarkm class Decl { 18155682Smarkm private DeclKind declKind; 18255682Smarkm private int index; 18355682Smarkm 18455682Smarkm Decl(DeclKind declKind, int index) { 18555682Smarkm this.declKind = declKind; 18655682Smarkm this.index = index; 187178825Sdfr } 18855682Smarkm 18955682Smarkm boolean hasKind(DeclKind declKind) { 19055682Smarkm return this.declKind == declKind; 191233294Sstas } 19255682Smarkm 193233294Sstas boolean isGeneric() { 194233294Sstas return typeVarsKind() == TypeVarsKind.Z_T; 195233294Sstas } 196178825Sdfr 197178825Sdfr TypeKind returnKind() { 198178825Sdfr return returnKinds[index]; 199178825Sdfr } 200178825Sdfr 201178825Sdfr TypeKind argumentsKind() { 202178825Sdfr return argumentKinds[index]; 203178825Sdfr } 204178825Sdfr 205178825Sdfr TypeVarsKind typeVarsKind() { 20655682Smarkm return typeVarsKinds[index]; 20755682Smarkm } 20855682Smarkm } 209178825Sdfr 21055682Smarkm CallKind callKind; 21155682Smarkm InputExpressionKind inputExpressionKind; 21255682Smarkm TypeKind[] returnKinds = new TypeKind[2]; 21355682Smarkm TypeKind[] argumentKinds = new TypeKind[2]; 21455682Smarkm TypeVarsKind[] typeVarsKinds = new TypeVarsKind[2]; 21555682Smarkm Decl[] decls = new Decl[2]; 21655682Smarkm 21755682Smarkm boolean arityFilter() { 21855682Smarkm return (callKind == CallKind.M || !decls[1].hasKind(DeclKind.NONE)) && 21955682Smarkm !decls[0].hasKind(DeclKind.NONE); 220102644Snectar } 221102644Snectar 222178825Sdfr boolean declFilter() { 223102644Snectar return Stream.of(decls) 224102644Snectar .filter(d -> d.hasKind(DeclKind.NONE)) 225102644Snectar .flatMap(d -> Stream.of(d.returnKind(), d.argumentsKind(), d.typeVarsKind())) 226178825Sdfr .noneMatch(tk -> tk.ordinal() != 0); 227178825Sdfr } 228178825Sdfr 229178825Sdfr boolean tvarFilter() { 230178825Sdfr return Stream.of(decls) 231178825Sdfr .filter(d -> !d.hasKind(DeclKind.NONE)) 232178825Sdfr .filter(d -> !d.isGeneric()) 233178825Sdfr .flatMap(d -> Stream.of(d.returnKind(), d.argumentsKind())) 234178825Sdfr .noneMatch(TypeKind::hasTypeVars); 235178825Sdfr } 236178825Sdfr 237178825Sdfr boolean inputExprFilter() { 238178825Sdfr return (inputExpressionKind != InputExpressionKind.B && inputExpressionKind != InputExpressionKind.B_STRING) || 239178825Sdfr Stream.of(decls).allMatch(d -> d.declKind == DeclKind.TWO); 240178825Sdfr } 241178825Sdfr 242102644Snectar @Override 243178825Sdfr public void doWork() throws Throwable { 244102644Snectar check(newCompilationTask() 245178825Sdfr .withSourceFromTemplate(sourceTemplate) 246178825Sdfr .analyze()); 247233294Sstas } 248233294Sstas 249233294Sstas void check(Result<Iterable<? extends Element>> result) { 250120945Snectar if (result.hasErrors()) { 251102644Snectar fail("compiler error:\n" + 252102644Snectar result.compilationInfo()); 253102644Snectar } 254102644Snectar } 255102644Snectar} 256102644Snectar