test/tools/javac/processing/filer/TestFilerConstraints.java

Tue, 24 Aug 2010 15:09:21 -0700

author
jjg
date
Tue, 24 Aug 2010 15:09:21 -0700
changeset 655
f3323b1c65ee
parent 554
9d9f26857129
child 699
d2aaaec153e8
permissions
-rw-r--r--

6929404: Filer.getResource(SOURCE_PATH, ...) does not work when -sourcepath contains >1 entry
Reviewed-by: darcy

duke@1 1 /*
ohair@554 2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
duke@1 7 * published by the Free Software Foundation.
duke@1 8 *
duke@1 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 13 * accompanied this code).
duke@1 14 *
duke@1 15 * You should have received a copy of the GNU General Public License version
duke@1 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 18 *
ohair@554 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554 20 * or visit www.oracle.com if you need additional information or have any
ohair@554 21 * questions.
duke@1 22 */
duke@1 23
duke@1 24 /*
duke@1 25 * @test
duke@1 26 * @bug 6380018 6453386 6457283
duke@1 27 * @summary Test that the constraints guaranteed by the Filer and maintained
duke@1 28 * @author Joseph D. Darcy
duke@1 29 * @build TestFilerConstraints
duke@1 30 * @compile -encoding iso-8859-1 -processor TestFilerConstraints -proc:only TestFilerConstraints.java
duke@1 31 */
duke@1 32
duke@1 33 import java.util.Set;
duke@1 34 import javax.annotation.processing.*;
duke@1 35 import javax.lang.model.SourceVersion;
duke@1 36 import static javax.lang.model.SourceVersion.*;
duke@1 37 import javax.lang.model.element.*;
duke@1 38 import javax.lang.model.util.*;
duke@1 39 import static javax.lang.model.util.ElementFilter.*;
duke@1 40 import static javax.tools.Diagnostic.Kind.*;
duke@1 41 import static javax.tools.StandardLocation.*;
duke@1 42
duke@1 43 import java.io.*;
duke@1 44 import java.nio.charset.Charset;
duke@1 45
duke@1 46 /**
duke@1 47 * A processor that verifies the explicit and implicit constraints in
duke@1 48 * the Filer contract are maintained:
duke@1 49 *
duke@1 50 * <blockquote>
duke@1 51 *
duke@1 52 * During each run of an annotation processing tool, a file with a
duke@1 53 * given pathname may be created only once. If that file already
duke@1 54 * exists before the first attempt to create it, the old contents
duke@1 55 * will be deleted. Any subsequent attempt to create the same file
duke@1 56 * during a run will throw a FilerException, as will attempting to
duke@1 57 * open both a class file and source file for the same type name.
duke@1 58 *
duke@1 59 * </blockquote>
duke@1 60 *
duke@1 61 * Specific checks will include:
duke@1 62 *
duke@1 63 * <ul>
duke@1 64 *
duke@1 65 * <li> Source and class files can be written to from either a Writer or an OutputStream.
duke@1 66 *
duke@1 67 * <li> Calling close multiple times does not re-register the file for
duke@1 68 * processing.
duke@1 69 *
duke@1 70 * </ul>
duke@1 71 */
duke@1 72 @SupportedAnnotationTypes("*")
duke@1 73 public class TestFilerConstraints extends AbstractProcessor {
duke@1 74 private int round = 0;
duke@1 75 private Messager messager;
duke@1 76 private Filer filer;
duke@1 77
duke@1 78 private PrintWriter pw_src1 = null;
duke@1 79 private PrintWriter pw_src2 = null;
duke@1 80 private OutputStream os_classFile1 = null;
duke@1 81 private Writer pw_classFile2 = null;
duke@1 82
duke@1 83 public boolean process(Set<? extends TypeElement> annotations,
duke@1 84 RoundEnvironment roundEnv) {
duke@1 85 round++;
duke@1 86
duke@1 87 try {
duke@1 88 switch(round) {
duke@1 89 // Open two source files
duke@1 90 case 1:
duke@1 91 pw_src1 = new PrintWriter(filer.createSourceFile("Src1").openWriter());
duke@1 92 pw_src1.println("class Src1 {}");
duke@1 93 pw_src1.close();
duke@1 94
duke@1 95 // Hold open across rounds
duke@1 96 pw_src2 = new PrintWriter(new OutputStreamWriter(filer.createSourceFile("Src2").openOutputStream()));
duke@1 97 break;
duke@1 98
duke@1 99 case 2:
duke@1 100 testExpectedType(roundEnv, "Src1");
duke@1 101
duke@1 102 // Close Src1 a second time
duke@1 103 pw_src1.close();
duke@1 104
duke@1 105 pw_src2.println("class Src2 {}");
duke@1 106 pw_src2.close();
duke@1 107
duke@1 108 break;
duke@1 109
duke@1 110 case 3:
duke@1 111 testExpectedType(roundEnv, "Src2");
duke@1 112
duke@1 113 // Close Src2 a second time
duke@1 114 pw_src2.close();
duke@1 115
duke@1 116 os_classFile1 = filer.createClassFile("ClassFile1").openOutputStream();
duke@1 117 for (int value : classFile1Bytes)
duke@1 118 os_classFile1.write((byte)value);
duke@1 119 os_classFile1.close();
duke@1 120
duke@1 121 break;
duke@1 122
duke@1 123 case 4:
duke@1 124 testExpectedType(roundEnv, "ClassFile1");
duke@1 125
duke@1 126 // Close a second time
duke@1 127 os_classFile1.close();
duke@1 128
duke@1 129 testReopening();
duke@1 130
duke@1 131 pw_classFile2 = new PrintWriter(filer.createClassFile("ClassFile2",
duke@1 132 (Element[])null).openWriter());
duke@1 133
duke@1 134 for(int byteVal : classFile2Bytes) {
duke@1 135 // int value = (0xff00 & (classFile2Bytes[i]<<8)) | classFile2Bytes[i+1];
duke@1 136 // System.out.print(Integer.toHexString(value));
duke@1 137 //if ((i % 4) == 0)
duke@1 138 // System.out.println();
duke@1 139 pw_classFile2.write((char) (0xff & byteVal));
duke@1 140 }
duke@1 141 pw_classFile2.close();
duke@1 142
duke@1 143 break;
duke@1 144
duke@1 145
duke@1 146
duke@1 147 case 5:
duke@1 148 testExpectedType(roundEnv, "ClassFile2");
duke@1 149 // Close a second time
duke@1 150 pw_classFile2.close();
duke@1 151
duke@1 152
duke@1 153 break;
duke@1 154
duke@1 155 case 6:
duke@1 156 if (!roundEnv.processingOver() && !roundEnv.errorRaised())
duke@1 157 throw new RuntimeException("Bad round state: " + roundEnv);
duke@1 158 break;
duke@1 159
duke@1 160 default:
duke@1 161 throw new RuntimeException("Unexpected round number!");
duke@1 162 }
duke@1 163 } catch (IOException ioe) {
duke@1 164 throw new RuntimeException(ioe);
duke@1 165 }
duke@1 166
duke@1 167 return true;
duke@1 168 }
duke@1 169
duke@1 170 public SourceVersion getSupportedSourceVersion() {
duke@1 171 return SourceVersion.latest();
duke@1 172 }
duke@1 173
duke@1 174 public void init(ProcessingEnvironment processingEnv) {
duke@1 175 super.init(processingEnv);
duke@1 176 messager = processingEnv.getMessager();
duke@1 177 filer = processingEnv.getFiler();
duke@1 178
duke@1 179 }
duke@1 180
duke@1 181 /**
duke@1 182 * Test that the single expected expected type, name, is the root
duke@1 183 * element.
duke@1 184 */
duke@1 185 private void testExpectedType(RoundEnvironment roundEnv, String name) {
duke@1 186 if (!roundEnv.getRootElements().isEmpty()) {
duke@1 187 for(TypeElement type : typesIn(roundEnv.getRootElements())) {
duke@1 188 if (!name.contentEquals(type.getSimpleName()))
duke@1 189 throw new RuntimeException("Unexpected type " + type.getSimpleName());
duke@1 190 }
duke@1 191 } else
duke@1 192 throw new RuntimeException("Unexpected empty root elements.");
duke@1 193 }
duke@1 194
duke@1 195 private void testReopening() throws IOException {
duke@1 196 String[] names = {"Src1", "Src2", "ClassFile1"};
duke@1 197 for (String name : names) {
duke@1 198 try {
duke@1 199 filer.createSourceFile(name);
duke@1 200 throw new RuntimeException("Opened a source file for type " + name);
duke@1 201 } catch (FilerException fe) {;}
duke@1 202
duke@1 203 try {
duke@1 204 filer.createClassFile(name);
duke@1 205 throw new RuntimeException("Opened a class file for type " + name);
duke@1 206 } catch (FilerException fe) {;}
duke@1 207 }
duke@1 208
duke@1 209 // Try to open a resource over a source file
duke@1 210 try {
duke@1 211 filer.createResource(SOURCE_OUTPUT, "", "Src1.java");
duke@1 212 throw new RuntimeException("Opened a text file over Src1.java!");
duke@1 213 } catch (FilerException fe) {;}
duke@1 214
duke@1 215 // Try to open a resource over a class file
duke@1 216 try {
duke@1 217 filer.createResource(CLASS_OUTPUT, "", "ClassFile1.class");
duke@1 218 throw new RuntimeException("Opened a text file over Src1.java!");
duke@1 219 } catch (FilerException fe) {;}
duke@1 220
duke@1 221 }
duke@1 222
duke@1 223 private int[] classFile1Bytes =
duke@1 224 {202, 254, 186, 190, 0, 0, 0, 50,
duke@1 225 0, 13, 10, 0, 3, 0, 10, 7,
duke@1 226 0, 11, 7, 0, 12, 1, 0, 6,
duke@1 227 60, 105, 110, 105, 116, 62, 1, 0,
duke@1 228 3, 40, 41, 86, 1, 0, 4, 67,
duke@1 229 111, 100, 101, 1, 0, 15, 76, 105,
duke@1 230 110, 101, 78, 117, 109, 98, 101, 114,
duke@1 231 84, 97, 98, 108, 101, 1, 0, 10,
duke@1 232 83, 111, 117, 114, 99, 101, 70, 105,
duke@1 233 108, 101, 1, 0, 15, 67, 108, 97,
duke@1 234 115, 115, 70, 105, 108, 101, 49, 46,
duke@1 235 106, 97, 118, 97, 12, 0, 4, 0,
duke@1 236 5, 1, 0, 10, 67, 108, 97, 115,
duke@1 237 115, 70, 105, 108, 101, 49, 1, 0,
duke@1 238 16, 106, 97, 118, 97, 47, 108, 97,
duke@1 239 110, 103, 47, 79, 98, 106, 101, 99,
duke@1 240 116, 0, 33, 0, 2, 0, 3, 0,
duke@1 241 0, 0, 0, 0, 1, 0, 1, 0,
duke@1 242 4, 0, 5, 0, 1, 0, 6, 0,
duke@1 243 0, 0, 29, 0, 1, 0, 1, 0,
duke@1 244 0, 0, 5, 42, 183, 0, 1, 177,
duke@1 245 0, 0, 0, 1, 0, 7, 0, 0,
duke@1 246 0, 6, 0, 1, 0, 0, 0, 1,
duke@1 247 0, 1, 0, 8, 0, 0, 0, 2,
duke@1 248 0, 9,};
duke@1 249
duke@1 250 private int[] classFile2Bytes =
duke@1 251 {202, 254, 186, 190, 0, 0, 0, 50,
duke@1 252 0, 13, 10, 0, 3, 0, 10, 7,
duke@1 253 0, 11, 7, 0, 12, 1, 0, 6,
duke@1 254 60, 105, 110, 105, 116, 62, 1, 0,
duke@1 255 3, 40, 41, 86, 1, 0, 4, 67,
duke@1 256 111, 100, 101, 1, 0, 15, 76, 105,
duke@1 257 110, 101, 78, 117, 109, 98, 101, 114,
duke@1 258 84, 97, 98, 108, 101, 1, 0, 10,
duke@1 259 83, 111, 117, 114, 99, 101, 70, 105,
duke@1 260 108, 101, 1, 0, 15, 67, 108, 97,
duke@1 261 115, 115, 70, 105, 108, 101, 50, 46,
duke@1 262 106, 97, 118, 97, 12, 0, 4, 0,
duke@1 263 5, 1, 0, 10, 67, 108, 97, 115,
duke@1 264 115, 70, 105, 108, 101, 50, 1, 0,
duke@1 265 16, 106, 97, 118, 97, 47, 108, 97,
duke@1 266 110, 103, 47, 79, 98, 106, 101, 99,
duke@1 267 116, 0, 33, 0, 2, 0, 3, 0,
duke@1 268 0, 0, 0, 0, 1, 0, 1, 0,
duke@1 269 4, 0, 5, 0, 1, 0, 6, 0,
duke@1 270 0, 0, 29, 0, 1, 0, 1, 0,
duke@1 271 0, 0, 5, 42, 183, 0, 1, 177,
duke@1 272 0, 0, 0, 1, 0, 7, 0, 0,
duke@1 273 0, 6, 0, 1, 0, 0, 0, 1,
duke@1 274 0, 1, 0, 8, 0, 0, 0, 2,
duke@1 275 0, 9,};
duke@1 276 }

mercurial