T7086601b.java revision 1105
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill/*
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill *
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * This code is free software; you can redistribute it and/or modify it
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * under the terms of the GNU General Public License version 2 only, as
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * published by the Free Software Foundation.
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill *
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * This code is distributed in the hope that it will be useful, but WITHOUT
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * version 2 for more details (a copy is included in the LICENSE file that
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * accompanied this code).
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill *
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * You should have received a copy of the GNU General Public License version
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * 2 along with this work; if not, write to the Free Software Foundation,
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill *
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill * or visit www.oracle.com if you need additional information or have any
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostler * questions.
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostler */
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostler
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostler/*
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostler * @test
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostler * @bug 7086601
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostler * @summary Error message bug: cause for method mismatch is 'null'
689f6de487d18c407321c66141acff7b223706b3sean oneill */
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostler
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostlerimport com.sun.source.util.JavacTask;
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostlerimport java.net.URI;
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostlerimport java.util.Arrays;
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostlerimport java.util.ArrayList;
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostlerimport javax.tools.Diagnostic;
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostlerimport javax.tools.JavaCompiler;
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostlerimport javax.tools.JavaFileObject;
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostlerimport javax.tools.SimpleJavaFileObject;
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostlerimport javax.tools.StandardJavaFileManager;
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostlerimport javax.tools.ToolProvider;
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostler
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostler
ec67ff5275de072883193d284121ba1b97404bb3Phil Ostlerpublic class T7086601b {
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill static int checkCount = 0;
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill
d39dadc72724b84431f2aebfdf107344bc099173sean oneill enum TypeKind {
d39dadc72724b84431f2aebfdf107344bc099173sean oneill STRING("String", false),
d39dadc72724b84431f2aebfdf107344bc099173sean oneill INTEGER("Integer", false),
d39dadc72724b84431f2aebfdf107344bc099173sean oneill NUMBER("Number", false),
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill SERIALIZABLE("java.io.Serializable", true),
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill CLONEABLE("Cloneable", true),
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill X("X", false),
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill Y("Y", false),
d39dadc72724b84431f2aebfdf107344bc099173sean oneill Z("Z", false);
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill String typeStr;
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill boolean isInterface;
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill private TypeKind(String typeStr, boolean isInterface) {
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill this.typeStr = typeStr;
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill this.isInterface = isInterface;
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill }
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill boolean isSubtypeof(TypeKind other) {
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill return (this == INTEGER && other == NUMBER ||
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill this == Z && other == Y ||
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill this == other);
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill }
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill }
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill enum MethodCallKind {
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill ARITY_ONE("m(a1);", 1),
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill ARITY_TWO("m(a1, a2);", 2),
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill ARITY_THREE("m(a1, a2, a3);", 3);
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill String invokeString;
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill int arity;
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill private MethodCallKind(String invokeString, int arity) {
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill this.invokeString = invokeString;
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill this.arity = arity;
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill }
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill }
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill public static void main(String... args) throws Exception {
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill //create default shared JavaCompiler - reused across multiple compilations
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill for (TypeKind a1 : TypeKind.values()) {
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill for (TypeKind a2 : TypeKind.values()) {
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill for (TypeKind a3 : TypeKind.values()) {
16feaab5fbad30aecf489c34b3777a6b76025803sean oneill for (MethodCallKind mck : MethodCallKind.values()) {
new T7086601b(a1, a2, a3, mck).run(comp, fm);
}
}
}
}
System.out.println("Total check executed: " + checkCount);
}
TypeKind a1;
TypeKind a2;
TypeKind a3;
MethodCallKind mck;
JavaSource source;
DiagnosticChecker diagChecker;
T7086601b(TypeKind a1, TypeKind a2, TypeKind a3, MethodCallKind mck) {
this.a1 = a1;
this.a2 = a2;
this.a3 = a3;
this.mck = mck;
this.source = new JavaSource();
this.diagChecker = new DiagnosticChecker();
}
class JavaSource extends SimpleJavaFileObject {
final String bodyTemplate = "import java.util.List;\n"+
"class Test {\n" +
" <Z> void m(List<? super Z> l1) { }\n" +
" <Z> void m(List<? super Z> l1, List<? super Z> l2) { }\n" +
" <Z> void m(List<? super Z> l1, List<? super Z> l2, List<? super Z> l3) { }\n" +
" <X,Y,Z extends Y> void test(List<#A1> a1, List<#A2> a2, List<#A3> a3) { #MC } }";
String source;
public JavaSource() {
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
source = bodyTemplate.replace("#A1", a1.typeStr)
.replace("#A2", a2.typeStr).replace("#A3", a3.typeStr)
.replace("#MC", mck.invokeString);
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return source;
}
}
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
null, null, Arrays.asList(source));
try {
ct.analyze();
} catch (Throwable ex) {
throw new AssertionError("Error thron when compiling the following code:\n" + source.getCharContent(true));
}
check();
}
void check() {
checkCount++;
boolean errorExpected = false;
if (mck.arity > 1) {
TypeKind[] argtypes = { a1, a2, a3 };
ArrayList<TypeKind> classes = new ArrayList<>();
for (int i = 0 ; i < mck.arity ; i ++ ) {
if (!argtypes[i].isInterface) {
classes.add(argtypes[i]);
}
}
boolean glb_exists = true;
for (TypeKind arg_i : classes) {
glb_exists = true;
for (TypeKind arg_j : classes) {
if (!arg_i.isSubtypeof(arg_j)) {
glb_exists = false;
break;
}
}
if (glb_exists) break;
}
errorExpected = !glb_exists;
}
if (errorExpected != diagChecker.errorFound) {
throw new Error("invalid diagnostics for source:\n" +
source.getCharContent(true) +
"\nFound error: " + diagChecker.errorFound +
"\nExpected error: " + errorExpected);
}
}
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
boolean errorFound;
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
errorFound = true;
}
}
}
}