langtools/test/tools/javac/defaultMethods/static/hiding/InterfaceMethodHidingTest.java
changeset 15377 515846bb6637
child 22448 a85fbad9d687
equal deleted inserted replaced
15376:32b49791817d 15377:515846bb6637
       
     1 /*
       
     2  * Copyright (c) 2012, 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 8005166
       
    27  * @summary Add support for static interface methods
       
    28  *          Smoke test for static interface method hiding
       
    29  */
       
    30 
       
    31 import com.sun.source.util.JavacTask;
       
    32 import java.net.URI;
       
    33 import java.util.Arrays;
       
    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 InterfaceMethodHidingTest {
       
    43 
       
    44     static int checkCount = 0;
       
    45 
       
    46     enum SignatureKind {
       
    47         VOID_INTEGER("void m(Integer s)", "return;"),
       
    48         STRING_INTEGER("String m(Integer s)", "return null;"),
       
    49         VOID_STRING("void m(String s)", "return;"),
       
    50         STRING_STRING("String m(String s)", "return null;");
       
    51 
       
    52         String sigStr;
       
    53         String retStr;
       
    54 
       
    55         SignatureKind(String sigStr, String retStr) {
       
    56             this.sigStr = sigStr;
       
    57             this.retStr = retStr;
       
    58         }
       
    59 
       
    60         boolean overrideEquivalentWith(SignatureKind s2) {
       
    61             switch (this) {
       
    62                 case VOID_INTEGER:
       
    63                 case STRING_INTEGER:
       
    64                     return s2 == VOID_INTEGER || s2 == STRING_INTEGER;
       
    65                 case VOID_STRING:
       
    66                 case STRING_STRING:
       
    67                     return s2 == VOID_STRING || s2 == STRING_STRING;
       
    68                 default:
       
    69                     throw new AssertionError("bad signature kind");
       
    70             }
       
    71         }
       
    72     }
       
    73 
       
    74     enum MethodKind {
       
    75         VIRTUAL("", "#M #S;"),
       
    76         STATIC("static", "#M #S { #BE; #R }"),
       
    77         DEFAULT("default", "#M #S { #BE; #R }");
       
    78 
       
    79         String modStr;
       
    80         String methTemplate;
       
    81 
       
    82         MethodKind(String modStr, String methTemplate) {
       
    83             this.modStr = modStr;
       
    84             this.methTemplate = methTemplate;
       
    85         }
       
    86 
       
    87         boolean inherithed() {
       
    88             return this != STATIC;
       
    89         }
       
    90 
       
    91         static boolean overrides(MethodKind mk1, SignatureKind sk1, MethodKind mk2, SignatureKind sk2) {
       
    92             return sk1 == sk2 &&
       
    93                     mk2.inherithed() &&
       
    94                     mk1 != STATIC;
       
    95         }
       
    96 
       
    97         String getBody(BodyExpr be, SignatureKind sk) {
       
    98             return methTemplate.replaceAll("#BE", be.bodyExprStr)
       
    99                     .replaceAll("#R", sk.retStr)
       
   100                     .replaceAll("#M", modStr)
       
   101                     .replaceAll("#S", sk.sigStr);
       
   102         }
       
   103     }
       
   104 
       
   105     enum BodyExpr {
       
   106         NONE(""),
       
   107         THIS("Object o = this");
       
   108 
       
   109         String bodyExprStr;
       
   110 
       
   111         BodyExpr(String bodyExprStr) {
       
   112             this.bodyExprStr = bodyExprStr;
       
   113         }
       
   114 
       
   115         boolean allowed(MethodKind mk) {
       
   116             return this == NONE ||
       
   117                     mk != MethodKind.STATIC;
       
   118         }
       
   119     }
       
   120 
       
   121     public static void main(String... args) throws Exception {
       
   122 
       
   123         //create default shared JavaCompiler - reused across multiple compilations
       
   124         JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
       
   125         StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
       
   126 
       
   127         for (MethodKind mk1 : MethodKind.values()) {
       
   128             for (SignatureKind sk1 : SignatureKind.values()) {
       
   129                 for (BodyExpr be1 : BodyExpr.values()) {
       
   130                     for (MethodKind mk2 : MethodKind.values()) {
       
   131                         for (SignatureKind sk2 : SignatureKind.values()) {
       
   132                             for (BodyExpr be2 : BodyExpr.values()) {
       
   133                                 for (MethodKind mk3 : MethodKind.values()) {
       
   134                                     for (SignatureKind sk3 : SignatureKind.values()) {
       
   135                                         for (BodyExpr be3 : BodyExpr.values()) {
       
   136                                             new InterfaceMethodHidingTest(mk1, mk2, mk3, sk1, sk2, sk3, be1, be2, be3).run(comp, fm);
       
   137                                         }
       
   138                                     }
       
   139                                 }
       
   140                             }
       
   141                         }
       
   142                     }
       
   143                 }
       
   144             }
       
   145         }
       
   146         System.out.println("Total check executed: " + checkCount);
       
   147     }
       
   148 
       
   149     MethodKind mk1, mk2, mk3;
       
   150     SignatureKind sk1, sk2, sk3;
       
   151     BodyExpr be1, be2, be3;
       
   152     JavaSource source;
       
   153     DiagnosticChecker diagChecker;
       
   154 
       
   155     InterfaceMethodHidingTest(MethodKind mk1, MethodKind mk2, MethodKind mk3,
       
   156             SignatureKind sk1, SignatureKind sk2, SignatureKind sk3, BodyExpr be1, BodyExpr be2, BodyExpr be3) {
       
   157         this.mk1 = mk1;
       
   158         this.mk2 = mk2;
       
   159         this.mk3 = mk3;
       
   160         this.sk1 = sk1;
       
   161         this.sk2 = sk2;
       
   162         this.sk3 = sk3;
       
   163         this.be1 = be1;
       
   164         this.be2 = be2;
       
   165         this.be3 = be3;
       
   166         this.source = new JavaSource();
       
   167         this.diagChecker = new DiagnosticChecker();
       
   168     }
       
   169 
       
   170     class JavaSource extends SimpleJavaFileObject {
       
   171 
       
   172         String template = "interface Sup {\n" +
       
   173                           "   default void sup() { }\n" +
       
   174                           "}\n" +
       
   175                           "interface A extends Sup {\n" +
       
   176                           "   #M1\n" +
       
   177                           "}\n" +
       
   178                           "interface B extends A, Sup {\n" +
       
   179                           "   #M2\n" +
       
   180                           "}\n" +
       
   181                           "interface C extends B, Sup {\n" +
       
   182                           "   #M3\n" +
       
   183                           "}\n";
       
   184 
       
   185         String source;
       
   186 
       
   187         public JavaSource() {
       
   188             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
       
   189             source = template.replaceAll("#M1", mk1.getBody(be1, sk1))
       
   190                     .replaceAll("#M2", mk2.getBody(be2, sk2))
       
   191                     .replaceAll("#M3", mk3.getBody(be3, sk3));
       
   192         }
       
   193 
       
   194         @Override
       
   195         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
       
   196             return source;
       
   197         }
       
   198     }
       
   199 
       
   200     void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
       
   201         JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
       
   202                 Arrays.asList("-XDallowStaticInterfaceMethods"), null, Arrays.asList(source));
       
   203         try {
       
   204             ct.analyze();
       
   205         } catch (Throwable ex) {
       
   206             throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
       
   207         }
       
   208         check();
       
   209     }
       
   210 
       
   211     void check() {
       
   212         boolean errorExpected =
       
   213                 !be1.allowed(mk1) || !be2.allowed(mk2) || !be3.allowed(mk3);
       
   214 
       
   215         if (mk1.inherithed()) {
       
   216             errorExpected |=
       
   217                     sk2.overrideEquivalentWith(sk1) && !MethodKind.overrides(mk2, sk2, mk1, sk1) ||
       
   218                     sk3.overrideEquivalentWith(sk1) && !MethodKind.overrides(mk3, sk3, mk1, sk1);
       
   219         }
       
   220 
       
   221         if (mk2.inherithed()) {
       
   222             errorExpected |=
       
   223                     sk3.overrideEquivalentWith(sk2) && !MethodKind.overrides(mk3, sk3, mk2, sk2);
       
   224         }
       
   225 
       
   226         checkCount++;
       
   227         if (diagChecker.errorFound != errorExpected) {
       
   228             throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) +
       
   229                     "\nfound error: " + diagChecker.errorFound);
       
   230         }
       
   231     }
       
   232 
       
   233     static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
       
   234 
       
   235         boolean errorFound;
       
   236 
       
   237         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
       
   238             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
       
   239                 errorFound = true;
       
   240             }
       
   241         }
       
   242     }
       
   243 }