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

changeset 1513
cf84b07a82db
child 2227
998b10c43157
equal deleted inserted replaced
1512:b12ffdfa1341 1513:cf84b07a82db
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 }

mercurial