langtools/test/tools/javac/generics/inference/7086601/T7086601b.java
changeset 10628 dca7012223bc
child 11381 890ea587d133
equal deleted inserted replaced
10627:d8e900b62e02 10628:dca7012223bc
       
     1 /*
       
     2  * Copyright (c) 2011, 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 7086601
       
    27  * @summary Error message bug: cause for method mismatch is 'null'
       
    28  */
       
    29 
       
    30 import com.sun.source.util.JavacTask;
       
    31 import java.net.URI;
       
    32 import java.util.Arrays;
       
    33 import java.util.ArrayList;
       
    34 import javax.tools.Diagnostic;
       
    35 import javax.tools.JavaCompiler;
       
    36 import javax.tools.JavaFileObject;
       
    37 import javax.tools.SimpleJavaFileObject;
       
    38 import javax.tools.StandardJavaFileManager;
       
    39 import javax.tools.ToolProvider;
       
    40 
       
    41 
       
    42 public class T7086601b {
       
    43 
       
    44     static int checkCount = 0;
       
    45 
       
    46     enum TypeKind {
       
    47         STRING("String", false),
       
    48         INTEGER("Integer", false),
       
    49         NUMBER("Number", false),
       
    50         SERIALIZABLE("java.io.Serializable", true),
       
    51         CLONEABLE("Cloneable", true),
       
    52         X("X", false),
       
    53         Y("Y", false),
       
    54         Z("Z", false);
       
    55 
       
    56         String typeStr;
       
    57         boolean isInterface;
       
    58 
       
    59         private TypeKind(String typeStr, boolean isInterface) {
       
    60             this.typeStr = typeStr;
       
    61             this.isInterface = isInterface;
       
    62         }
       
    63 
       
    64         boolean isSubtypeof(TypeKind other) {
       
    65             return (this == INTEGER && other == NUMBER ||
       
    66                     this == Z && other == Y ||
       
    67                     this == other);
       
    68         }
       
    69     }
       
    70 
       
    71     enum MethodCallKind {
       
    72         ARITY_ONE("m(a1);", 1),
       
    73         ARITY_TWO("m(a1, a2);", 2),
       
    74         ARITY_THREE("m(a1, a2, a3);", 3);
       
    75 
       
    76         String invokeString;
       
    77         int arity;
       
    78 
       
    79         private MethodCallKind(String invokeString, int arity) {
       
    80             this.invokeString = invokeString;
       
    81             this.arity = arity;
       
    82         }
       
    83     }
       
    84 
       
    85     public static void main(String... args) throws Exception {
       
    86 
       
    87         //create default shared JavaCompiler - reused across multiple compilations
       
    88         JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
       
    89         StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
       
    90 
       
    91         for (TypeKind a1 : TypeKind.values()) {
       
    92             for (TypeKind a2 : TypeKind.values()) {
       
    93                 for (TypeKind a3 : TypeKind.values()) {
       
    94                     for (MethodCallKind mck : MethodCallKind.values()) {
       
    95                         new T7086601b(a1, a2, a3, mck).run(comp, fm);
       
    96                     }
       
    97                 }
       
    98             }
       
    99         }
       
   100         System.out.println("Total check executed: " + checkCount);
       
   101     }
       
   102 
       
   103     TypeKind a1;
       
   104     TypeKind a2;
       
   105     TypeKind a3;
       
   106     MethodCallKind mck;
       
   107     JavaSource source;
       
   108     DiagnosticChecker diagChecker;
       
   109 
       
   110     T7086601b(TypeKind a1, TypeKind a2, TypeKind a3, MethodCallKind mck) {
       
   111         this.a1 = a1;
       
   112         this.a2 = a2;
       
   113         this.a3 = a3;
       
   114         this.mck = mck;
       
   115         this.source = new JavaSource();
       
   116         this.diagChecker = new DiagnosticChecker();
       
   117     }
       
   118 
       
   119     class JavaSource extends SimpleJavaFileObject {
       
   120 
       
   121         final String bodyTemplate = "import java.util.List;\n"+
       
   122                               "class Test {\n" +
       
   123                               "   <Z> void m(List<? super Z> l1) { }\n" +
       
   124                               "   <Z> void m(List<? super Z> l1, List<? super Z> l2) { }\n" +
       
   125                               "   <Z> void m(List<? super Z> l1, List<? super Z> l2, List<? super Z> l3) { }\n" +
       
   126                               "   <X,Y,Z extends Y> void test(List<#A1> a1, List<#A2> a2, List<#A3> a3) { #MC } }";
       
   127 
       
   128         String source;
       
   129 
       
   130         public JavaSource() {
       
   131             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
       
   132             source = bodyTemplate.replace("#A1", a1.typeStr)
       
   133                              .replace("#A2", a2.typeStr).replace("#A3", a3.typeStr)
       
   134                              .replace("#MC", mck.invokeString);
       
   135         }
       
   136 
       
   137         @Override
       
   138         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
       
   139             return source;
       
   140         }
       
   141     }
       
   142 
       
   143     void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
       
   144         JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
       
   145                 null, null, Arrays.asList(source));
       
   146         try {
       
   147             ct.analyze();
       
   148         } catch (Throwable ex) {
       
   149             throw new AssertionError("Error thron when compiling the following code:\n" + source.getCharContent(true));
       
   150         }
       
   151         check();
       
   152     }
       
   153 
       
   154     void check() {
       
   155         checkCount++;
       
   156 
       
   157         boolean errorExpected = false;
       
   158 
       
   159         if (mck.arity > 1) {
       
   160             TypeKind[] argtypes = { a1, a2, a3 };
       
   161             ArrayList<TypeKind> classes = new ArrayList<>();
       
   162             for (int i = 0 ; i < mck.arity ; i ++ ) {
       
   163                 if (!argtypes[i].isInterface) {
       
   164                     classes.add(argtypes[i]);
       
   165                 }
       
   166             }
       
   167             boolean glb_exists = true;
       
   168             for (TypeKind arg_i : classes) {
       
   169                 glb_exists = true;
       
   170                 for (TypeKind arg_j : classes) {
       
   171                     if (!arg_i.isSubtypeof(arg_j)) {
       
   172                         glb_exists = false;
       
   173                         break;
       
   174                     }
       
   175                 }
       
   176                 if (glb_exists) break;
       
   177             }
       
   178             errorExpected = !glb_exists;
       
   179         }
       
   180 
       
   181         if (errorExpected != diagChecker.errorFound) {
       
   182             throw new Error("invalid diagnostics for source:\n" +
       
   183                 source.getCharContent(true) +
       
   184                 "\nFound error: " + diagChecker.errorFound +
       
   185                 "\nExpected error: " + errorExpected);
       
   186         }
       
   187     }
       
   188 
       
   189     static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
       
   190 
       
   191         boolean errorFound;
       
   192 
       
   193         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
       
   194             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
       
   195                 errorFound = true;
       
   196             }
       
   197         }
       
   198     }
       
   199 }