test/tools/javac/defaultMethods/static/hiding/InterfaceMethodHidingTest.java

Mon, 21 Jan 2013 20:19:53 +0000

author
mcimadamore
date
Mon, 21 Jan 2013 20:19:53 +0000
changeset 1513
cf84b07a82db
child 2227
998b10c43157
permissions
-rw-r--r--

8005166: Add support for static interface methods
Summary: Support public static interface methods
Reviewed-by: jjg

     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  */
    24 /*
    25  * @test
    26  * @bug 8005166
    27  * @summary Add support for static interface methods
    28  *          Smoke test for static interface method hiding
    29  */
    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;
    42 public class InterfaceMethodHidingTest {
    44     static int checkCount = 0;
    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;");
    52         String sigStr;
    53         String retStr;
    55         SignatureKind(String sigStr, String retStr) {
    56             this.sigStr = sigStr;
    57             this.retStr = retStr;
    58         }
    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     }
    74     enum MethodKind {
    75         VIRTUAL("", "#M #S;"),
    76         STATIC("static", "#M #S { #BE; #R }"),
    77         DEFAULT("default", "#M #S { #BE; #R }");
    79         String modStr;
    80         String methTemplate;
    82         MethodKind(String modStr, String methTemplate) {
    83             this.modStr = modStr;
    84             this.methTemplate = methTemplate;
    85         }
    87         boolean inherithed() {
    88             return this != STATIC;
    89         }
    91         static boolean overrides(MethodKind mk1, SignatureKind sk1, MethodKind mk2, SignatureKind sk2) {
    92             return sk1 == sk2 &&
    93                     mk2.inherithed() &&
    94                     mk1 != STATIC;
    95         }
    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     }
   105     enum BodyExpr {
   106         NONE(""),
   107         THIS("Object o = this");
   109         String bodyExprStr;
   111         BodyExpr(String bodyExprStr) {
   112             this.bodyExprStr = bodyExprStr;
   113         }
   115         boolean allowed(MethodKind mk) {
   116             return this == NONE ||
   117                     mk != MethodKind.STATIC;
   118         }
   119     }
   121     public static void main(String... args) throws Exception {
   123         //create default shared JavaCompiler - reused across multiple compilations
   124         JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
   125         StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
   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     }
   149     MethodKind mk1, mk2, mk3;
   150     SignatureKind sk1, sk2, sk3;
   151     BodyExpr be1, be2, be3;
   152     JavaSource source;
   153     DiagnosticChecker diagChecker;
   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     }
   170     class JavaSource extends SimpleJavaFileObject {
   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";
   185         String source;
   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         }
   194         @Override
   195         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   196             return source;
   197         }
   198     }
   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     }
   211     void check() {
   212         boolean errorExpected =
   213                 !be1.allowed(mk1) || !be2.allowed(mk2) || !be3.allowed(mk3);
   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         }
   221         if (mk2.inherithed()) {
   222             errorExpected |=
   223                     sk3.overrideEquivalentWith(sk2) && !MethodKind.overrides(mk3, sk3, mk2, sk2);
   224         }
   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     }
   233     static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   235         boolean errorFound;
   237         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   238             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
   239                 errorFound = true;
   240             }
   241         }
   242     }
   243 }

mercurial