Mon, 02 Sep 2013 22:38:36 +0100
8016177: structural most specific and stuckness
Reviewed-by: jjg, vromero
Contributed-by: maurizio.cimadamore@oracle.com
1 /*
2 * Copyright (c) 2011, 2013, 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 7030606 8006694
27 * @summary Project-coin: multi-catch types should be pairwise disjoint
28 * temporarily workaround combo tests are causing time out in several platforms
29 * @library ../../lib
30 * @build JavacTestingAbstractThreadedTest
31 * @run main/othervm DisjunctiveTypeWellFormednessTest
32 */
34 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
35 // see JDK-8006746
37 import java.net.URI;
38 import java.util.Arrays;
39 import javax.tools.Diagnostic;
40 import javax.tools.JavaFileObject;
41 import javax.tools.SimpleJavaFileObject;
42 import com.sun.source.util.JavacTask;
44 public class DisjunctiveTypeWellFormednessTest
45 extends JavacTestingAbstractThreadedTest
46 implements Runnable {
48 enum Alternative {
49 EXCEPTION("Exception"),
50 RUNTIME_EXCEPTION("RuntimeException"),
51 IO_EXCEPTION("java.io.IOException"),
52 FILE_NOT_FOUND_EXCEPTION("java.io.FileNotFoundException"),
53 ILLEGAL_ARGUMENT_EXCEPTION("IllegalArgumentException");
55 String exceptionStr;
57 private Alternative(String exceptionStr) {
58 this.exceptionStr = exceptionStr;
59 }
61 static String makeDisjunctiveType(Alternative... alternatives) {
62 StringBuilder buf = new StringBuilder();
63 String sep = "";
64 for (Alternative alternative : alternatives) {
65 buf.append(sep);
66 buf.append(alternative.exceptionStr);
67 sep = "|";
68 }
69 return buf.toString();
70 }
72 boolean disjoint(Alternative that) {
73 return disjoint[this.ordinal()][that.ordinal()];
74 }
76 static boolean[][] disjoint = {
77 // Exception RuntimeException IOException FileNotFoundException IllegalArgumentException
78 /*Exception*/ { false, false, false, false, false },
79 /*RuntimeException*/ { false, false, true, true, false },
80 /*IOException*/ { false, true, false, false, true },
81 /*FileNotFoundException*/ { false, true, false, false, true },
82 /*IllegalArgumentException*/ { false, false, true, true, false }
83 };
84 }
86 enum Arity {
87 ONE(1),
88 TWO(2),
89 THREE(3),
90 FOUR(4),
91 FIVE(5);
93 int n;
95 private Arity(int n) {
96 this.n = n;
97 }
98 }
100 public static void main(String... args) throws Exception {
101 for (Arity arity : Arity.values()) {
102 for (Alternative a1 : Alternative.values()) {
103 if (arity == Arity.ONE) {
104 pool.execute(new DisjunctiveTypeWellFormednessTest(a1));
105 continue;
106 }
107 for (Alternative a2 : Alternative.values()) {
108 if (arity == Arity.TWO) {
109 pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2));
110 continue;
111 }
112 for (Alternative a3 : Alternative.values()) {
113 if (arity == Arity.THREE) {
114 pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2, a3));
115 continue;
116 }
117 for (Alternative a4 : Alternative.values()) {
118 if (arity == Arity.FOUR) {
119 pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2, a3, a4));
120 continue;
121 }
122 for (Alternative a5 : Alternative.values()) {
123 pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2, a3, a4, a5));
124 }
125 }
126 }
127 }
128 }
129 }
131 checkAfterExec(false);
132 }
134 Alternative[] alternatives;
135 JavaSource source;
136 DiagnosticChecker diagChecker;
138 DisjunctiveTypeWellFormednessTest(Alternative... alternatives) {
139 this.alternatives = alternatives;
140 this.source = new JavaSource();
141 this.diagChecker = new DiagnosticChecker();
142 }
144 class JavaSource extends SimpleJavaFileObject {
146 String template = "class Test {\n" +
147 "void test() {\n" +
148 "try {} catch (#T e) {}\n" +
149 "}\n" +
150 "}\n";
152 String source;
154 public JavaSource() {
155 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
156 source = template.replace("#T", Alternative.makeDisjunctiveType(alternatives));
157 }
159 @Override
160 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
161 return source;
162 }
163 }
165 @Override
166 public void run() {
167 JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
168 null, null, Arrays.asList(source));
169 try {
170 ct.analyze();
171 } catch (Throwable t) {
172 processException(t);
173 return;
174 }
175 check();
176 }
178 void check() {
180 int non_disjoint = 0;
181 int i = 0;
182 for (Alternative a1 : alternatives) {
183 int j = 0;
184 for (Alternative a2 : alternatives) {
185 if (i == j) continue;
186 if (!a1.disjoint(a2)) {
187 non_disjoint++;
188 break;
189 }
190 j++;
191 }
192 i++;
193 }
195 if (non_disjoint != diagChecker.errorsFound) {
196 throw new Error("invalid diagnostics for source:\n" +
197 source.getCharContent(true) +
198 "\nFound errors: " + diagChecker.errorsFound +
199 "\nExpected errors: " + non_disjoint);
200 }
201 }
203 static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
205 int errorsFound;
207 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
208 if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
209 diagnostic.getCode().startsWith("compiler.err.multicatch.types.must.be.disjoint")) {
210 errorsFound++;
211 }
212 }
213 }
215 }