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) 2006, 2010, 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 6380018 6453386 6457283
27 * @summary Test that the constraints guaranteed by the Filer and maintained
28 * @author Joseph D. Darcy
29 * @library /tools/javac/lib
30 * @build TestFilerConstraints
31 * @compile -encoding iso-8859-1 -processor TestFilerConstraints -proc:only TestFilerConstraints.java
32 */
34 import java.util.Set;
35 import javax.annotation.processing.*;
36 import javax.lang.model.SourceVersion;
37 import static javax.lang.model.SourceVersion.*;
38 import javax.lang.model.element.*;
39 import javax.lang.model.util.*;
40 import static javax.lang.model.util.ElementFilter.*;
41 import static javax.tools.Diagnostic.Kind.*;
42 import static javax.tools.StandardLocation.*;
44 import java.io.*;
45 import java.nio.charset.Charset;
47 /**
48 * A processor that verifies the explicit and implicit constraints in
49 * the Filer contract are maintained:
50 *
51 * <blockquote>
52 *
53 * During each run of an annotation processing tool, a file with a
54 * given pathname may be created only once. If that file already
55 * exists before the first attempt to create it, the old contents
56 * will be deleted. Any subsequent attempt to create the same file
57 * during a run will throw a FilerException, as will attempting to
58 * open both a class file and source file for the same type name.
59 *
60 * </blockquote>
61 *
62 * Specific checks will include:
63 *
64 * <ul>
65 *
66 * <li> Source and class files can be written to from either a Writer or an OutputStream.
67 *
68 * <li> Calling close multiple times does not re-register the file for
69 * processing.
70 *
71 * </ul>
72 */
73 public class TestFilerConstraints extends JavacTestingAbstractProcessor {
74 private int round = 0;
76 private PrintWriter pw_src1 = null;
77 private PrintWriter pw_src2 = null;
78 private OutputStream os_classFile1 = null;
79 private Writer pw_classFile2 = null;
81 public boolean process(Set<? extends TypeElement> annotations,
82 RoundEnvironment roundEnv) {
83 round++;
85 try {
86 switch(round) {
87 // Open two source files
88 case 1:
89 pw_src1 = new PrintWriter(filer.createSourceFile("Src1").openWriter());
90 pw_src1.println("class Src1 {}");
91 pw_src1.close();
93 // Hold open across rounds
94 pw_src2 = new PrintWriter(new OutputStreamWriter(filer.createSourceFile("Src2").openOutputStream()));
95 break;
97 case 2:
98 testExpectedType(roundEnv, "Src1");
100 // Close Src1 a second time
101 pw_src1.close();
103 pw_src2.println("class Src2 {}");
104 pw_src2.close();
106 break;
108 case 3:
109 testExpectedType(roundEnv, "Src2");
111 // Close Src2 a second time
112 pw_src2.close();
114 os_classFile1 = filer.createClassFile("ClassFile1").openOutputStream();
115 for (int value : classFile1Bytes)
116 os_classFile1.write((byte)value);
117 os_classFile1.close();
119 break;
121 case 4:
122 testExpectedType(roundEnv, "ClassFile1");
124 // Close a second time
125 os_classFile1.close();
127 testReopening();
129 pw_classFile2 = new PrintWriter(filer.createClassFile("ClassFile2",
130 (Element[])null).openWriter());
132 for(int byteVal : classFile2Bytes) {
133 // int value = (0xff00 & (classFile2Bytes[i]<<8)) | classFile2Bytes[i+1];
134 // System.out.print(Integer.toHexString(value));
135 //if ((i % 4) == 0)
136 // System.out.println();
137 pw_classFile2.write((char) (0xff & byteVal));
138 }
139 pw_classFile2.close();
141 break;
145 case 5:
146 testExpectedType(roundEnv, "ClassFile2");
147 // Close a second time
148 pw_classFile2.close();
151 break;
153 case 6:
154 if (!roundEnv.processingOver() && !roundEnv.errorRaised())
155 throw new RuntimeException("Bad round state: " + roundEnv);
156 break;
158 default:
159 throw new RuntimeException("Unexpected round number!");
160 }
161 } catch (IOException ioe) {
162 throw new RuntimeException(ioe);
163 }
165 return true;
166 }
168 /**
169 * Test that the single expected expected type, name, is the root
170 * element.
171 */
172 private void testExpectedType(RoundEnvironment roundEnv, String name) {
173 if (!roundEnv.getRootElements().isEmpty()) {
174 for(TypeElement type : typesIn(roundEnv.getRootElements())) {
175 if (!name.contentEquals(type.getSimpleName()))
176 throw new RuntimeException("Unexpected type " + type.getSimpleName());
177 }
178 } else
179 throw new RuntimeException("Unexpected empty root elements.");
180 }
182 private void testReopening() throws IOException {
183 String[] names = {"Src1", "Src2", "ClassFile1"};
184 for (String name : names) {
185 try {
186 filer.createSourceFile(name);
187 throw new RuntimeException("Opened a source file for type " + name);
188 } catch (FilerException fe) {;}
190 try {
191 filer.createClassFile(name);
192 throw new RuntimeException("Opened a class file for type " + name);
193 } catch (FilerException fe) {;}
194 }
196 // Try to open a resource over a source file
197 try {
198 filer.createResource(SOURCE_OUTPUT, "", "Src1.java");
199 throw new RuntimeException("Opened a text file over Src1.java!");
200 } catch (FilerException fe) {;}
202 // Try to open a resource over a class file
203 try {
204 filer.createResource(CLASS_OUTPUT, "", "ClassFile1.class");
205 throw new RuntimeException("Opened a text file over Src1.java!");
206 } catch (FilerException fe) {;}
208 }
210 private int[] classFile1Bytes =
211 {202, 254, 186, 190, 0, 0, 0, 50,
212 0, 13, 10, 0, 3, 0, 10, 7,
213 0, 11, 7, 0, 12, 1, 0, 6,
214 60, 105, 110, 105, 116, 62, 1, 0,
215 3, 40, 41, 86, 1, 0, 4, 67,
216 111, 100, 101, 1, 0, 15, 76, 105,
217 110, 101, 78, 117, 109, 98, 101, 114,
218 84, 97, 98, 108, 101, 1, 0, 10,
219 83, 111, 117, 114, 99, 101, 70, 105,
220 108, 101, 1, 0, 15, 67, 108, 97,
221 115, 115, 70, 105, 108, 101, 49, 46,
222 106, 97, 118, 97, 12, 0, 4, 0,
223 5, 1, 0, 10, 67, 108, 97, 115,
224 115, 70, 105, 108, 101, 49, 1, 0,
225 16, 106, 97, 118, 97, 47, 108, 97,
226 110, 103, 47, 79, 98, 106, 101, 99,
227 116, 0, 33, 0, 2, 0, 3, 0,
228 0, 0, 0, 0, 1, 0, 1, 0,
229 4, 0, 5, 0, 1, 0, 6, 0,
230 0, 0, 29, 0, 1, 0, 1, 0,
231 0, 0, 5, 42, 183, 0, 1, 177,
232 0, 0, 0, 1, 0, 7, 0, 0,
233 0, 6, 0, 1, 0, 0, 0, 1,
234 0, 1, 0, 8, 0, 0, 0, 2,
235 0, 9,};
237 private int[] classFile2Bytes =
238 {202, 254, 186, 190, 0, 0, 0, 50,
239 0, 13, 10, 0, 3, 0, 10, 7,
240 0, 11, 7, 0, 12, 1, 0, 6,
241 60, 105, 110, 105, 116, 62, 1, 0,
242 3, 40, 41, 86, 1, 0, 4, 67,
243 111, 100, 101, 1, 0, 15, 76, 105,
244 110, 101, 78, 117, 109, 98, 101, 114,
245 84, 97, 98, 108, 101, 1, 0, 10,
246 83, 111, 117, 114, 99, 101, 70, 105,
247 108, 101, 1, 0, 15, 67, 108, 97,
248 115, 115, 70, 105, 108, 101, 50, 46,
249 106, 97, 118, 97, 12, 0, 4, 0,
250 5, 1, 0, 10, 67, 108, 97, 115,
251 115, 70, 105, 108, 101, 50, 1, 0,
252 16, 106, 97, 118, 97, 47, 108, 97,
253 110, 103, 47, 79, 98, 106, 101, 99,
254 116, 0, 33, 0, 2, 0, 3, 0,
255 0, 0, 0, 0, 1, 0, 1, 0,
256 4, 0, 5, 0, 1, 0, 6, 0,
257 0, 0, 29, 0, 1, 0, 1, 0,
258 0, 0, 5, 42, 183, 0, 1, 177,
259 0, 0, 0, 1, 0, 7, 0, 0,
260 0, 6, 0, 1, 0, 0, 0, 1,
261 0, 1, 0, 8, 0, 0, 0, 2,
262 0, 9,};
263 }