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