1 /* 2 * Copyright (c) 2012, 2015, 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 8129962 27 * @summary Add support for static interface methods 28 * Smoke test for static interface method hiding 29 * @enablePreview 30 * @library /tools/javac/lib 31 * @modules jdk.compiler/com.sun.tools.javac.api 32 * jdk.compiler/com.sun.tools.javac.file 33 * jdk.compiler/com.sun.tools.javac.util 34 * @build combo.ComboTestHelper 35 * @run main InterfaceMethodHidingTest 36 */ 37 38 import java.io.IOException; 39 40 import combo.ComboInstance; 41 import combo.ComboParameter; 42 import combo.ComboTask.Result; 43 import combo.ComboTestHelper; 44 45 public class InterfaceMethodHidingTest extends ComboInstance<InterfaceMethodHidingTest> { 46 47 enum SignatureKind implements ComboParameter { 48 VOID_INTEGER("void m(Integer s)", false), 49 STRING_INTEGER("String m(Integer s)", true), 50 VOID_STRING("void m(String s)", false), 51 STRING_STRING("String m(String s)", true); 52 53 String sigStr; 54 boolean needsReturn; 55 56 SignatureKind(String sigStr, boolean needsReturn) { 57 this.sigStr = sigStr; 58 this.needsReturn = needsReturn; 59 } 60 61 boolean overrideEquivalentWith(SignatureKind s2) { 62 switch (this) { 63 case VOID_INTEGER: 64 case STRING_INTEGER: 65 return s2 == VOID_INTEGER || s2 == STRING_INTEGER; 66 case VOID_STRING: 67 case STRING_STRING: 68 return s2 == VOID_STRING || s2 == STRING_STRING; 69 default: 70 throw new AssertionError("bad signature kind"); 71 } 72 } 73 74 @Override 75 public String expand(String optParameter) { 76 return sigStr; 77 } 78 } 79 80 enum MethodKind implements ComboParameter { 81 VIRTUAL("#{SIG[#IDX]};"), 82 STATIC("static #{SIG[#IDX]} { #{BODY[#IDX]}; #{RET.#IDX} }"), 83 DEFAULT("default #{SIG[#IDX]} { #{BODY[#IDX]}; #{RET.#IDX} }"); 84 85 String methTemplate; 86 87 MethodKind(String methTemplate) { 88 this.methTemplate = methTemplate; 89 } 90 91 boolean inherithed() { 92 return this != STATIC; 93 } 94 95 static boolean overrides(MethodKind mk1, SignatureKind sk1, MethodKind mk2, SignatureKind sk2) { 96 return sk1 == sk2 && 97 mk2.inherithed() && 98 mk1 != STATIC; 99 } 100 101 @Override 102 public String expand(String optParameter) { 103 return methTemplate.replaceAll("#IDX", optParameter); 104 } 105 } 106 107 enum BodyExpr implements ComboParameter { 108 NONE(""), 109 THIS("Object o = this"); 110 111 String bodyExprStr; 112 113 BodyExpr(String bodyExprStr) { 114 this.bodyExprStr = bodyExprStr; 115 } 116 117 boolean allowed(MethodKind mk) { 118 return this == NONE || 119 mk != MethodKind.STATIC; 120 } 121 122 @Override 123 public String expand(String optParameter) { 124 return bodyExprStr; 125 } 126 } 127 128 public static void main(String... args) throws Exception { 129 new ComboTestHelper<InterfaceMethodHidingTest>() 130 .withArrayDimension("SIG", (x, sig, idx) -> x.signatureKinds[idx] = sig, 3, SignatureKind.values()) 131 .withArrayDimension("BODY", (x, body, idx) -> x.bodyExprs[idx] = body, 3, BodyExpr.values()) 132 .withArrayDimension("MET", (x, meth, idx) -> x.methodKinds[idx] = meth, 3, MethodKind.values()) 133 .run(InterfaceMethodHidingTest::new); 134 } 135 136 MethodKind[] methodKinds = new MethodKind[3]; 137 SignatureKind[] signatureKinds = new SignatureKind[3]; 138 BodyExpr[] bodyExprs = new BodyExpr[3]; 139 140 String template = "interface Sup {\n" + 141 " default void sup() { }\n" + 142 "}\n" + 143 "interface A extends Sup {\n" + 144 " #{MET[0].0}\n" + 145 "}\n" + 146 "interface B extends A, Sup {\n" + 147 " #{MET[1].1}\n" + 148 "}\n" + 149 "interface C extends B, Sup {\n" + 150 " #{MET[2].2}\n" + 151 "}\n"; 152 153 @Override 154 public void doWork() throws IOException { 155 newCompilationTask() 156 .withOption("-XDallowStaticInterfaceMethods") 157 .withSourceFromTemplate(template, this::returnExpr) 158 .analyze(this::check); 159 } 160 161 ComboParameter returnExpr(String name) { 162 switch (name) { 163 case "RET": 164 return optParameter -> { 165 int idx = new Integer(optParameter); 166 return signatureKinds[idx].needsReturn ? "return null;" : "return;"; 167 }; 168 default: 169 return null; 170 } 171 } 172 173 void check(Result<?> res) { 174 boolean errorExpected = !bodyExprs[0].allowed(methodKinds[0]) || 175 !bodyExprs[1].allowed(methodKinds[1]) || 176 !bodyExprs[2].allowed(methodKinds[2]); 177 178 if (methodKinds[0].inherithed()) { 179 errorExpected |= signatureKinds[1].overrideEquivalentWith(signatureKinds[0]) && 180 !MethodKind.overrides(methodKinds[1], signatureKinds[1], methodKinds[0], signatureKinds[0]) || 181 signatureKinds[2].overrideEquivalentWith(signatureKinds[0]) && 182 !MethodKind.overrides(methodKinds[2], signatureKinds[2], methodKinds[0], signatureKinds[0]); 183 } 184 185 if (methodKinds[1].inherithed()) { 186 errorExpected |= signatureKinds[2].overrideEquivalentWith(signatureKinds[1]) && 187 !MethodKind.overrides(methodKinds[2], signatureKinds[2], methodKinds[1], signatureKinds[1]); 188 } 189 190 if (res.hasErrors() != errorExpected) { 191 fail("Problem when compiling source:\n" + res.compilationInfo() + 192 "\nfound error: " + res.hasErrors()); 193 } 194 } 195 }