langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java
changeset 16809 5acfcb821d65
parent 15375 d2529dc91d77
child 20249 93f8eae31092
equal deleted inserted replaced
16808:90b98d194b75 16809:5acfcb821d65
    26  * @bug 8002099
    26  * @bug 8002099
    27  * @summary Add support for intersection types in cast expression
    27  * @summary Add support for intersection types in cast expression
    28  */
    28  */
    29 
    29 
    30 import com.sun.source.util.JavacTask;
    30 import com.sun.source.util.JavacTask;
    31 import com.sun.tools.javac.util.List;
       
    32 import com.sun.tools.javac.util.ListBuffer;
    31 import com.sun.tools.javac.util.ListBuffer;
    33 import java.net.URI;
    32 import java.net.URI;
       
    33 import java.util.ArrayList;
    34 import java.util.Arrays;
    34 import java.util.Arrays;
       
    35 import java.util.List;
    35 import javax.tools.Diagnostic;
    36 import javax.tools.Diagnostic;
    36 import javax.tools.JavaCompiler;
    37 import javax.tools.JavaCompiler;
    37 import javax.tools.JavaFileObject;
    38 import javax.tools.JavaFileObject;
    38 import javax.tools.SimpleJavaFileObject;
    39 import javax.tools.SimpleJavaFileObject;
    39 import javax.tools.StandardJavaFileManager;
    40 import javax.tools.StandardJavaFileManager;
    43 
    44 
    44     static int checkCount = 0;
    45     static int checkCount = 0;
    45 
    46 
    46     enum BoundKind {
    47     enum BoundKind {
    47         INTF,
    48         INTF,
    48         CLASS,
    49         CLASS;
    49         SAM,
       
    50         ZAM;
       
    51     }
    50     }
    52 
    51 
    53     enum MethodKind {
    52     enum MethodKind {
    54         NONE,
    53         NONE(false),
    55         ABSTRACT,
    54         ABSTRACT_M(true),
    56         DEFAULT;
    55         DEFAULT_M(false),
       
    56         ABSTRACT_G(true),
       
    57         DEFAULT_G(false);
       
    58 
       
    59         boolean isAbstract;
       
    60 
       
    61         MethodKind(boolean isAbstract) {
       
    62             this.isAbstract = isAbstract;
       
    63         }
    57     }
    64     }
    58 
    65 
    59     enum TypeKind {
    66     enum TypeKind {
    60         A("interface A { }\n", "A", BoundKind.ZAM),
    67         A("interface A { }\n", "A", BoundKind.INTF, MethodKind.NONE),
    61         B("interface B { default void m() { } }\n", "B", BoundKind.ZAM),
    68         B("interface B { default void m() { } }\n", "B", BoundKind.INTF, MethodKind.DEFAULT_M),
    62         C("interface C { void m(); }\n", "C", BoundKind.SAM),
    69         C("interface C { void m(); }\n", "C", BoundKind.INTF, MethodKind.ABSTRACT_M),
    63         D("interface D extends B { }\n", "D", BoundKind.ZAM),
    70         D("interface D extends B { }\n", "D", BoundKind.INTF, MethodKind.DEFAULT_M),
    64         E("interface E extends C { }\n", "E", BoundKind.SAM),
    71         E("interface E extends C { }\n", "E", BoundKind.INTF, MethodKind.ABSTRACT_M),
    65         F("interface F extends C { void g(); }\n", "F", BoundKind.INTF),
    72         F("interface F extends C { void g(); }\n", "F", BoundKind.INTF, MethodKind.ABSTRACT_G, MethodKind.ABSTRACT_M),
    66         G("interface G extends B { void g(); }\n", "G", BoundKind.SAM),
    73         G("interface G extends B { void g(); }\n", "G", BoundKind.INTF, MethodKind.ABSTRACT_G, MethodKind.DEFAULT_M),
    67         H("interface H extends A { void g(); }\n", "H", BoundKind.SAM),
    74         H("interface H extends A { void g(); }\n", "H", BoundKind.INTF, MethodKind.ABSTRACT_G),
    68         OBJECT("", "Object", BoundKind.CLASS),
    75         OBJECT("", "Object", BoundKind.CLASS),
    69         STRING("", "String", BoundKind.CLASS);
    76         STRING("", "String", BoundKind.CLASS);
    70 
    77 
    71         String declStr;
    78         String declStr;
    72         String typeStr;
    79         String typeStr;
    73         BoundKind boundKind;
    80         BoundKind boundKind;
    74 
    81         MethodKind[] methodKinds;
    75         private TypeKind(String declStr, String typeStr, BoundKind boundKind) {
    82 
       
    83         private TypeKind(String declStr, String typeStr, BoundKind boundKind, MethodKind... methodKinds) {
    76             this.declStr = declStr;
    84             this.declStr = declStr;
    77             this.typeStr = typeStr;
    85             this.typeStr = typeStr;
    78             this.boundKind = boundKind;
    86             this.boundKind = boundKind;
       
    87             this.methodKinds = methodKinds;
    79         }
    88         }
    80 
    89 
    81         boolean compatibleSupertype(TypeKind tk) {
    90         boolean compatibleSupertype(TypeKind tk) {
    82             if (tk == this) return true;
    91             if (tk == this) return true;
    83             switch (tk) {
    92             switch (tk) {
   261         checkCount++;
   270         checkCount++;
   262 
   271 
   263         boolean errorExpected = !cInfo.wellFormed();
   272         boolean errorExpected = !cInfo.wellFormed();
   264 
   273 
   265         if (ek.isFunctional) {
   274         if (ek.isFunctional) {
   266             //first bound must be a SAM
   275             List<MethodKind> mks = new ArrayList<>();
   267             errorExpected |= cInfo.types[0].boundKind != BoundKind.SAM;
   276             for (TypeKind tk : cInfo.types) {
   268             if (cInfo.types.length > 1) {
   277                 if (tk.boundKind == BoundKind.CLASS) {
   269                 //additional bounds must be ZAMs
   278                     errorExpected = true;
   270                 for (int i = 1; i < cInfo.types.length; i++) {
   279                     break;
   271                     errorExpected |= cInfo.types[i].boundKind != BoundKind.ZAM;
   280                 } else {
   272                 }
   281                     mks = mergeMethods(mks, Arrays.asList(tk.methodKinds));
   273             }
   282                 }
       
   283             }
       
   284             int abstractCount = 0;
       
   285             for (MethodKind mk : mks) {
       
   286                 if (mk.isAbstract) {
       
   287                     abstractCount++;
       
   288                 }
       
   289             }
       
   290             errorExpected |= abstractCount != 1;
   274         }
   291         }
   275 
   292 
   276         if (errorExpected != diagChecker.errorFound) {
   293         if (errorExpected != diagChecker.errorFound) {
   277             throw new Error("invalid diagnostics for source:\n" +
   294             throw new Error("invalid diagnostics for source:\n" +
   278                 source.getCharContent(true) +
   295                 source.getCharContent(true) +
   279                 "\nFound error: " + diagChecker.errorFound +
   296                 "\nFound error: " + diagChecker.errorFound +
   280                 "\nExpected error: " + errorExpected);
   297                 "\nExpected error: " + errorExpected);
   281         }
   298         }
   282     }
   299     }
   283 
   300 
       
   301     List<MethodKind> mergeMethods(List<MethodKind> l1, List<MethodKind> l2) {
       
   302         List<MethodKind> mergedMethods = new ArrayList<>(l1);
       
   303         for (MethodKind mk2 : l2) {
       
   304             boolean add = !mergedMethods.contains(mk2);
       
   305             switch (mk2) {
       
   306                 case ABSTRACT_G:
       
   307                     add = add && !mergedMethods.contains(MethodKind.DEFAULT_G);
       
   308                     break;
       
   309                 case ABSTRACT_M:
       
   310                     add = add && !mergedMethods.contains(MethodKind.DEFAULT_M);
       
   311                     break;
       
   312                 case DEFAULT_G:
       
   313                     mergedMethods.remove(MethodKind.ABSTRACT_G);
       
   314                 case DEFAULT_M:
       
   315                     mergedMethods.remove(MethodKind.ABSTRACT_M);
       
   316                 case NONE:
       
   317                     add = false;
       
   318                     break;
       
   319             }
       
   320             if (add) {
       
   321                 mergedMethods.add(mk2);
       
   322             }
       
   323         }
       
   324         return mergedMethods;
       
   325     }
       
   326 
   284     static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   327     static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   285 
   328 
   286         boolean errorFound;
   329         boolean errorFound;
   287 
   330 
   288         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   331         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {