Fri, 24 Apr 2020 03:58:51 +0100
Merge
jjg@946 | 1 | /* |
katleman@1013 | 2 | * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. |
jjg@946 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
jjg@946 | 4 | * |
jjg@946 | 5 | * This code is free software; you can redistribute it and/or modify it |
jjg@946 | 6 | * under the terms of the GNU General Public License version 2 only, as |
jjg@946 | 7 | * published by the Free Software Foundation. |
jjg@946 | 8 | * |
jjg@946 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
jjg@946 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
jjg@946 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
jjg@946 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
jjg@946 | 13 | * accompanied this code). |
jjg@946 | 14 | * |
jjg@946 | 15 | * You should have received a copy of the GNU General Public License version |
jjg@946 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
jjg@946 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
jjg@946 | 18 | * |
jjg@946 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
jjg@946 | 20 | * or visit www.oracle.com if you need additional information or have any |
jjg@946 | 21 | * questions. |
jjg@946 | 22 | */ |
jjg@946 | 23 | |
jjg@946 | 24 | /* |
jjg@946 | 25 | * @test |
jjg@946 | 26 | * @bug 6437138 6482554 |
jjg@946 | 27 | * @summary JSR 199: Compiler doesn't diagnose crash in user code |
jjg@946 | 28 | * @library ../lib |
jjg@946 | 29 | * @build JavacTestingAbstractProcessor TestClientCodeWrapper |
jjg@946 | 30 | * @run main TestClientCodeWrapper |
jjg@946 | 31 | */ |
jjg@946 | 32 | |
jjg@946 | 33 | import java.io.*; |
jjg@946 | 34 | import java.lang.reflect.Method; |
jjg@946 | 35 | import java.net.URI; |
jjg@946 | 36 | import java.util.*; |
jjg@946 | 37 | import javax.annotation.processing.*; |
jjg@946 | 38 | import javax.lang.model.*; |
jjg@946 | 39 | import javax.lang.model.element.*; |
jjg@946 | 40 | import javax.tools.*; |
jjg@946 | 41 | import com.sun.source.util.*; |
jjg@946 | 42 | import com.sun.tools.javac.api.*; |
jjg@946 | 43 | import javax.tools.JavaFileObject.Kind; |
jjg@946 | 44 | |
jjg@946 | 45 | public class TestClientCodeWrapper extends JavacTestingAbstractProcessor { |
jjg@946 | 46 | public static void main(String... args) throws Exception { |
jjg@946 | 47 | new TestClientCodeWrapper().run(); |
jjg@946 | 48 | } |
jjg@946 | 49 | |
jjg@946 | 50 | /** |
jjg@946 | 51 | * Run a series of compilations, each with a different user-provided object |
jjg@946 | 52 | * configured to throw an exception when a specific method is invoked. |
jjg@946 | 53 | * Then, verify the exception is thrown as expected. |
jjg@946 | 54 | * |
jjg@946 | 55 | * Some methods are not invoked from the compiler, and are excluded from the test. |
jjg@946 | 56 | */ |
jjg@946 | 57 | void run() throws Exception { |
jjg@946 | 58 | JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); |
jjg@946 | 59 | defaultFileManager = compiler.getStandardFileManager(null, null, null); |
jjg@946 | 60 | |
jjg@946 | 61 | for (Method m: getMethodsExcept(JavaFileManager.class, "close", "getJavaFileForInput")) { |
jjg@946 | 62 | test(m); |
jjg@946 | 63 | } |
jjg@946 | 64 | |
jjg@946 | 65 | for (Method m: getMethodsExcept(FileObject.class, "delete")) { |
jjg@946 | 66 | test(m); |
jjg@946 | 67 | } |
jjg@946 | 68 | |
jjg@946 | 69 | for (Method m: getMethods(JavaFileObject.class)) { |
jjg@946 | 70 | test(m); |
jjg@946 | 71 | } |
jjg@946 | 72 | |
jjg@946 | 73 | for (Method m: getMethodsExcept(Processor.class, "getCompletions")) { |
jjg@946 | 74 | test(m); |
jjg@946 | 75 | } |
jjg@946 | 76 | |
jjg@946 | 77 | for (Method m: DiagnosticListener.class.getDeclaredMethods()) { |
jjg@946 | 78 | test(m); |
jjg@946 | 79 | } |
jjg@946 | 80 | |
jjg@946 | 81 | for (Method m: TaskListener.class.getDeclaredMethods()) { |
jjg@946 | 82 | test(m); |
jjg@946 | 83 | } |
jjg@946 | 84 | |
jjg@946 | 85 | if (errors > 0) |
jjg@946 | 86 | throw new Exception(errors + " errors occurred"); |
jjg@946 | 87 | } |
jjg@946 | 88 | |
jjg@946 | 89 | /** Get a sorted set of the methods declared on a class. */ |
jjg@946 | 90 | Set<Method> getMethods(Class<?> clazz) { |
jjg@946 | 91 | return getMethodsExcept(clazz, new String[0]); |
jjg@946 | 92 | } |
jjg@946 | 93 | |
jjg@946 | 94 | /** Get a sorted set of the methods declared on a class, excluding |
jjg@946 | 95 | * specified methods by name. */ |
jjg@946 | 96 | Set<Method> getMethodsExcept(Class<?> clazz, String... exclude) { |
jjg@946 | 97 | Set<Method> methods = new TreeSet<Method>(new Comparator<Method>() { |
jjg@946 | 98 | public int compare(Method m1, Method m2) { |
jjg@946 | 99 | return m1.toString().compareTo(m2.toString()); |
jjg@946 | 100 | } |
jjg@946 | 101 | }); |
jjg@946 | 102 | Set<String> e = new HashSet<String>(Arrays.asList(exclude)); |
jjg@946 | 103 | for (Method m: clazz.getDeclaredMethods()) { |
jjg@946 | 104 | if (!e.contains(m.getName())) |
jjg@946 | 105 | methods.add(m); |
jjg@946 | 106 | } |
jjg@946 | 107 | return methods; |
jjg@946 | 108 | } |
jjg@946 | 109 | |
jjg@946 | 110 | /** |
jjg@946 | 111 | * Test a method in a user supplied component, to verify javac's handling |
jjg@946 | 112 | * of any exceptions thrown by that method. |
jjg@946 | 113 | */ |
jjg@946 | 114 | void test(Method m) throws Exception { |
jjg@946 | 115 | testNum++; |
jjg@946 | 116 | |
jjg@946 | 117 | File extDirs = new File("empty-extdirs"); |
jjg@946 | 118 | extDirs.mkdirs(); |
jjg@946 | 119 | |
jjg@946 | 120 | File testClasses = new File("test" + testNum); |
jjg@946 | 121 | testClasses.mkdirs(); |
jjg@946 | 122 | defaultFileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(testClasses)); |
jjg@946 | 123 | |
jjg@946 | 124 | System.err.println("test " + testNum + ": " |
jjg@946 | 125 | + m.getDeclaringClass().getSimpleName() + "." + m.getName()); |
jjg@946 | 126 | |
jjg@946 | 127 | StringWriter sw = new StringWriter(); |
jjg@946 | 128 | PrintWriter pw = new PrintWriter(sw); |
jjg@946 | 129 | |
jjg@946 | 130 | List<String> javacOptions = Arrays.asList( |
jjg@946 | 131 | "-extdirs", extDirs.getPath(), // for use by filemanager handleOption |
jjg@946 | 132 | "-processor", TestClientCodeWrapper.class.getName() |
jjg@946 | 133 | ); |
jjg@946 | 134 | |
jjg@946 | 135 | List<String> classes = Collections.emptyList(); |
jjg@946 | 136 | |
jjg@946 | 137 | JavacTool tool = JavacTool.create(); |
jjg@946 | 138 | try { |
jjg@946 | 139 | JavacTask task = tool.getTask(pw, |
jjg@946 | 140 | getFileManager(m, defaultFileManager), |
jjg@946 | 141 | getDiagnosticListener(m, pw), |
jjg@946 | 142 | javacOptions, |
jjg@946 | 143 | classes, |
jjg@946 | 144 | getCompilationUnits(m)); |
jjg@946 | 145 | |
jjg@946 | 146 | if (isDeclaredIn(m, Processor.class)) |
jjg@946 | 147 | task.setProcessors(getProcessors(m)); |
jjg@946 | 148 | |
jjg@946 | 149 | if (isDeclaredIn(m, TaskListener.class)) |
jjg@946 | 150 | task.setTaskListener(getTaskListener(m, pw)); |
jjg@946 | 151 | |
jjg@946 | 152 | boolean ok = task.call(); |
jjg@946 | 153 | error("compilation " + (ok ? "succeeded" : "failed") + " unexpectedly"); |
jjg@946 | 154 | } catch (RuntimeException e) { |
jjg@946 | 155 | System.err.println("caught " + e); |
jjg@946 | 156 | if (e.getClass() == RuntimeException.class) { |
jjg@946 | 157 | Throwable cause = e.getCause(); |
jjg@946 | 158 | if (cause instanceof UserError) { |
jjg@946 | 159 | String expect = m.getName(); |
jjg@946 | 160 | String found = cause.getMessage(); |
jjg@946 | 161 | checkEqual("exception messaqe", expect, found); |
jjg@946 | 162 | } else { |
jjg@946 | 163 | cause.printStackTrace(System.err); |
jjg@946 | 164 | error("Unexpected exception: " + cause); |
jjg@946 | 165 | } |
jjg@946 | 166 | } else { |
jjg@946 | 167 | e.printStackTrace(System.err); |
jjg@946 | 168 | error("Unexpected exception: " + e); |
jjg@946 | 169 | } |
jjg@946 | 170 | } |
jjg@946 | 171 | |
jjg@946 | 172 | pw.close(); |
jjg@946 | 173 | String out = sw.toString(); |
jjg@946 | 174 | System.err.println(out); |
jjg@946 | 175 | } |
jjg@946 | 176 | |
jjg@946 | 177 | /** Get a file manager to use for the test compilation. */ |
jjg@946 | 178 | JavaFileManager getFileManager(Method m, JavaFileManager defaultFileManager) { |
jjg@946 | 179 | return isDeclaredIn(m, JavaFileManager.class, FileObject.class, JavaFileObject.class) |
jjg@946 | 180 | ? new UserFileManager(m, defaultFileManager) |
jjg@946 | 181 | : defaultFileManager; |
jjg@946 | 182 | } |
jjg@946 | 183 | |
jjg@946 | 184 | /** Get a diagnostic listener to use for the test compilation. */ |
jjg@946 | 185 | DiagnosticListener<JavaFileObject> getDiagnosticListener(Method m, PrintWriter out) { |
jjg@946 | 186 | return isDeclaredIn(m, DiagnosticListener.class) |
jjg@946 | 187 | ? new UserDiagnosticListener(m, out) |
jjg@946 | 188 | : null; |
jjg@946 | 189 | } |
jjg@946 | 190 | |
jjg@946 | 191 | /** Get a set of file objects to use for the test compilation. */ |
jjg@946 | 192 | Iterable<? extends JavaFileObject> getCompilationUnits(Method m) { |
jjg@946 | 193 | File testSrc = new File(System.getProperty("test.src")); |
jjg@946 | 194 | File thisSrc = new File(testSrc, TestClientCodeWrapper.class.getName() + ".java"); |
jjg@946 | 195 | Iterable<? extends JavaFileObject> files = defaultFileManager.getJavaFileObjects(thisSrc); |
jjg@946 | 196 | if (isDeclaredIn(m, FileObject.class, JavaFileObject.class)) |
jjg@946 | 197 | return Arrays.asList(new UserFileObject(m, files.iterator().next())); |
jjg@946 | 198 | else |
jjg@946 | 199 | return files; |
jjg@946 | 200 | } |
jjg@946 | 201 | |
jjg@946 | 202 | /** Get a set of annotation processors to use for the test compilation. */ |
jjg@946 | 203 | Iterable<? extends Processor> getProcessors(Method m) { |
jjg@946 | 204 | return Arrays.asList(new UserProcessor(m)); |
jjg@946 | 205 | } |
jjg@946 | 206 | |
jjg@946 | 207 | /** Get a task listener to use for the test compilation. */ |
jjg@946 | 208 | TaskListener getTaskListener(Method m, PrintWriter out) { |
jjg@946 | 209 | return new UserTaskListener(m, out); |
jjg@946 | 210 | } |
jjg@946 | 211 | |
jjg@946 | 212 | /** Check if two values are .equal, and report an error if not. */ |
jjg@946 | 213 | <T> void checkEqual(String label, T expect, T found) { |
jjg@946 | 214 | if (!expect.equals(found)) |
jjg@946 | 215 | error("Unexpected value for " + label + ": " + found + "; expected: " + expect); |
jjg@946 | 216 | } |
jjg@946 | 217 | |
jjg@946 | 218 | /** Report an error. */ |
jjg@946 | 219 | void error(String msg) { |
jjg@946 | 220 | System.err.println("Error: " + msg); |
jjg@946 | 221 | errors++; |
jjg@946 | 222 | } |
jjg@946 | 223 | |
jjg@946 | 224 | /** Check if a method is declared in any of a set of classes */ |
jjg@946 | 225 | static boolean isDeclaredIn(Method m, Class<?>... classes) { |
jjg@946 | 226 | Class<?> dc = m.getDeclaringClass(); |
jjg@946 | 227 | for (Class<?> c: classes) { |
jjg@946 | 228 | if (c == dc) return true; |
jjg@946 | 229 | } |
jjg@946 | 230 | return false; |
jjg@946 | 231 | } |
jjg@946 | 232 | |
jjg@946 | 233 | /** Throw an intentional error if the method has a given name. */ |
jjg@946 | 234 | static void throwUserExceptionIfNeeded(Method m, String name) { |
jjg@946 | 235 | if (m != null && m.getName().equals(name)) |
jjg@946 | 236 | throw new UserError(name); |
jjg@946 | 237 | } |
jjg@946 | 238 | |
jjg@946 | 239 | StandardJavaFileManager defaultFileManager; |
jjg@946 | 240 | int testNum; |
jjg@946 | 241 | int errors; |
jjg@946 | 242 | |
jjg@946 | 243 | //-------------------------------------------------------------------------- |
jjg@946 | 244 | |
jjg@946 | 245 | /** |
jjg@946 | 246 | * Processor used to trigger use of methods not normally used by javac. |
jjg@946 | 247 | */ |
jjg@946 | 248 | @Override |
jjg@946 | 249 | public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { |
jjg@946 | 250 | boolean firstRound = false; |
jjg@946 | 251 | for (Element e: roundEnv.getRootElements()) { |
jjg@946 | 252 | if (e.getSimpleName().contentEquals(TestClientCodeWrapper.class.getSimpleName())) |
jjg@946 | 253 | firstRound = true; |
jjg@946 | 254 | } |
jjg@946 | 255 | if (firstRound) { |
jjg@946 | 256 | try { |
jjg@946 | 257 | FileObject f1 = filer.getResource(StandardLocation.CLASS_PATH, "", |
jjg@946 | 258 | TestClientCodeWrapper.class.getName() + ".java"); |
jjg@946 | 259 | f1.openInputStream().close(); |
jjg@946 | 260 | f1.openReader(false).close(); |
jjg@946 | 261 | |
jjg@946 | 262 | FileObject f2 = filer.createResource( |
jjg@946 | 263 | StandardLocation.CLASS_OUTPUT, "", "f2.txt", (Element[]) null); |
jjg@946 | 264 | f2.openOutputStream().close(); |
jjg@946 | 265 | |
jjg@946 | 266 | FileObject f3 = filer.createResource( |
jjg@946 | 267 | StandardLocation.CLASS_OUTPUT, "", "f3.txt", (Element[]) null); |
jjg@946 | 268 | f3.openWriter().close(); |
jjg@946 | 269 | |
jjg@946 | 270 | JavaFileObject f4 = filer.createSourceFile("f4", (Element[]) null); |
jjg@946 | 271 | f4.openWriter().close(); |
jjg@946 | 272 | f4.getNestingKind(); |
jjg@946 | 273 | f4.getAccessLevel(); |
jjg@946 | 274 | |
jjg@946 | 275 | messager.printMessage(Diagnostic.Kind.NOTE, "informational note", |
jjg@946 | 276 | roundEnv.getRootElements().iterator().next()); |
jjg@946 | 277 | |
jjg@946 | 278 | } catch (IOException e) { |
jjg@946 | 279 | throw new UserError(e); |
jjg@946 | 280 | } |
jjg@946 | 281 | } |
jjg@946 | 282 | return true; |
jjg@946 | 283 | } |
jjg@946 | 284 | |
jjg@946 | 285 | //-------------------------------------------------------------------------- |
jjg@946 | 286 | |
jjg@946 | 287 | // <editor-fold defaultstate="collapsed" desc="User classes"> |
jjg@946 | 288 | |
jjg@946 | 289 | static class UserError extends Error { |
jjg@946 | 290 | private static final long serialVersionUID = 1L; |
jjg@946 | 291 | UserError(String msg) { |
jjg@946 | 292 | super(msg); |
jjg@946 | 293 | } |
jjg@946 | 294 | UserError(Throwable t) { |
jjg@946 | 295 | super(t); |
jjg@946 | 296 | } |
jjg@946 | 297 | } |
jjg@946 | 298 | |
jjg@946 | 299 | static class UserFileManager extends ForwardingJavaFileManager<JavaFileManager> { |
jjg@946 | 300 | Method fileManagerMethod; |
jjg@946 | 301 | Method fileObjectMethod; |
jjg@946 | 302 | |
jjg@946 | 303 | UserFileManager(Method m, JavaFileManager delegate) { |
jjg@946 | 304 | super(delegate); |
jjg@946 | 305 | if (isDeclaredIn(m, JavaFileManager.class)) { |
jjg@946 | 306 | fileManagerMethod = m; |
jjg@946 | 307 | } else if (isDeclaredIn(m, FileObject.class, JavaFileObject.class)) { |
jjg@946 | 308 | fileObjectMethod = m; |
jjg@946 | 309 | } else |
jjg@946 | 310 | assert false; |
jjg@946 | 311 | } |
jjg@946 | 312 | |
jjg@946 | 313 | @Override |
jjg@946 | 314 | public ClassLoader getClassLoader(Location location) { |
jjg@946 | 315 | throwUserExceptionIfNeeded(fileManagerMethod, "getClassLoader"); |
jjg@946 | 316 | return super.getClassLoader(location); |
jjg@946 | 317 | } |
jjg@946 | 318 | |
jjg@946 | 319 | @Override |
jjg@946 | 320 | public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException { |
jjg@946 | 321 | throwUserExceptionIfNeeded(fileManagerMethod, "list"); |
jjg@946 | 322 | return wrap(super.list(location, packageName, kinds, recurse)); |
jjg@946 | 323 | } |
jjg@946 | 324 | |
jjg@946 | 325 | @Override |
jjg@946 | 326 | public String inferBinaryName(Location location, JavaFileObject file) { |
jjg@946 | 327 | throwUserExceptionIfNeeded(fileManagerMethod, "inferBinaryName"); |
jjg@946 | 328 | return super.inferBinaryName(location, unwrap(file)); |
jjg@946 | 329 | } |
jjg@946 | 330 | |
jjg@946 | 331 | @Override |
jjg@946 | 332 | public boolean isSameFile(FileObject a, FileObject b) { |
jjg@946 | 333 | throwUserExceptionIfNeeded(fileManagerMethod, "isSameFile"); |
jjg@946 | 334 | return super.isSameFile(unwrap(a), unwrap(b)); |
jjg@946 | 335 | } |
jjg@946 | 336 | |
jjg@946 | 337 | @Override |
jjg@946 | 338 | public boolean handleOption(String current, Iterator<String> remaining) { |
jjg@946 | 339 | throwUserExceptionIfNeeded(fileManagerMethod, "handleOption"); |
jjg@946 | 340 | return super.handleOption(current, remaining); |
jjg@946 | 341 | } |
jjg@946 | 342 | |
jjg@946 | 343 | @Override |
jjg@946 | 344 | public boolean hasLocation(Location location) { |
jjg@946 | 345 | throwUserExceptionIfNeeded(fileManagerMethod, "hasLocation"); |
jjg@946 | 346 | return super.hasLocation(location); |
jjg@946 | 347 | } |
jjg@946 | 348 | |
jjg@946 | 349 | @Override |
jjg@946 | 350 | public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException { |
jjg@946 | 351 | throwUserExceptionIfNeeded(fileManagerMethod, "getJavaFileForInput"); |
jjg@946 | 352 | return wrap(super.getJavaFileForInput(location, className, kind)); |
jjg@946 | 353 | } |
jjg@946 | 354 | |
jjg@946 | 355 | @Override |
jjg@946 | 356 | public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException { |
jjg@946 | 357 | throwUserExceptionIfNeeded(fileManagerMethod, "getJavaFileForOutput"); |
jjg@946 | 358 | return wrap(super.getJavaFileForOutput(location, className, kind, sibling)); |
jjg@946 | 359 | } |
jjg@946 | 360 | |
jjg@946 | 361 | @Override |
jjg@946 | 362 | public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException { |
jjg@946 | 363 | throwUserExceptionIfNeeded(fileManagerMethod, "getFileForInput"); |
jjg@946 | 364 | return wrap(super.getFileForInput(location, packageName, relativeName)); |
jjg@946 | 365 | } |
jjg@946 | 366 | |
jjg@946 | 367 | @Override |
jjg@946 | 368 | public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException { |
jjg@946 | 369 | throwUserExceptionIfNeeded(fileManagerMethod, "getFileForOutput"); |
jjg@946 | 370 | return wrap(super.getFileForOutput(location, packageName, relativeName, sibling)); |
jjg@946 | 371 | } |
jjg@946 | 372 | |
jjg@946 | 373 | @Override |
jjg@946 | 374 | public void flush() throws IOException { |
jjg@946 | 375 | throwUserExceptionIfNeeded(fileManagerMethod, "flush"); |
jjg@946 | 376 | super.flush(); |
jjg@946 | 377 | } |
jjg@946 | 378 | |
jjg@946 | 379 | @Override |
jjg@946 | 380 | public void close() throws IOException { |
jjg@946 | 381 | throwUserExceptionIfNeeded(fileManagerMethod, "close"); |
jjg@946 | 382 | super.close(); |
jjg@946 | 383 | } |
jjg@946 | 384 | |
jjg@946 | 385 | @Override |
jjg@946 | 386 | public int isSupportedOption(String option) { |
jjg@946 | 387 | throwUserExceptionIfNeeded(fileManagerMethod, "isSupportedOption"); |
jjg@946 | 388 | return super.isSupportedOption(option); |
jjg@946 | 389 | } |
jjg@946 | 390 | |
jjg@946 | 391 | public FileObject wrap(FileObject fo) { |
jjg@946 | 392 | if (fileObjectMethod == null) |
jjg@946 | 393 | return fo; |
jjg@946 | 394 | return new UserFileObject(fileObjectMethod, (JavaFileObject)fo); |
jjg@946 | 395 | } |
jjg@946 | 396 | |
jjg@946 | 397 | FileObject unwrap(FileObject fo) { |
jjg@946 | 398 | if (fo instanceof UserFileObject) |
jjg@946 | 399 | return ((UserFileObject) fo).unwrap(); |
jjg@946 | 400 | else |
jjg@946 | 401 | return fo; |
jjg@946 | 402 | } |
jjg@946 | 403 | |
jjg@946 | 404 | public JavaFileObject wrap(JavaFileObject fo) { |
jjg@946 | 405 | if (fileObjectMethod == null) |
jjg@946 | 406 | return fo; |
jjg@946 | 407 | return new UserFileObject(fileObjectMethod, fo); |
jjg@946 | 408 | } |
jjg@946 | 409 | |
jjg@946 | 410 | public Iterable<JavaFileObject> wrap(Iterable<? extends JavaFileObject> list) { |
jjg@946 | 411 | List<JavaFileObject> wrapped = new ArrayList<JavaFileObject>(); |
jjg@946 | 412 | for (JavaFileObject fo : list) |
jjg@946 | 413 | wrapped.add(wrap(fo)); |
jjg@946 | 414 | return Collections.unmodifiableList(wrapped); |
jjg@946 | 415 | } |
jjg@946 | 416 | |
jjg@946 | 417 | JavaFileObject unwrap(JavaFileObject fo) { |
jjg@946 | 418 | if (fo instanceof UserFileObject) |
jjg@946 | 419 | return ((UserFileObject) fo).unwrap(); |
jjg@946 | 420 | else |
jjg@946 | 421 | return fo; |
jjg@946 | 422 | } |
jjg@946 | 423 | } |
jjg@946 | 424 | |
jjg@946 | 425 | static class UserFileObject extends ForwardingJavaFileObject<JavaFileObject> { |
jjg@946 | 426 | Method method; |
jjg@946 | 427 | |
jjg@946 | 428 | UserFileObject(Method m, JavaFileObject delegate) { |
jjg@946 | 429 | super(delegate); |
jjg@946 | 430 | assert isDeclaredIn(m, FileObject.class, JavaFileObject.class); |
jjg@946 | 431 | this.method = m; |
jjg@946 | 432 | } |
jjg@946 | 433 | |
jjg@946 | 434 | JavaFileObject unwrap() { |
jjg@946 | 435 | return fileObject; |
jjg@946 | 436 | } |
jjg@946 | 437 | |
jjg@946 | 438 | @Override |
jjg@946 | 439 | public Kind getKind() { |
jjg@946 | 440 | throwUserExceptionIfNeeded(method, "getKind"); |
jjg@946 | 441 | return super.getKind(); |
jjg@946 | 442 | } |
jjg@946 | 443 | |
jjg@946 | 444 | @Override |
jjg@946 | 445 | public boolean isNameCompatible(String simpleName, Kind kind) { |
jjg@946 | 446 | throwUserExceptionIfNeeded(method, "isNameCompatible"); |
jjg@946 | 447 | return super.isNameCompatible(simpleName, kind); |
jjg@946 | 448 | } |
jjg@946 | 449 | |
jjg@946 | 450 | @Override |
jjg@946 | 451 | public NestingKind getNestingKind() { |
jjg@946 | 452 | throwUserExceptionIfNeeded(method, "getNestingKind"); |
jjg@946 | 453 | return super.getNestingKind(); |
jjg@946 | 454 | } |
jjg@946 | 455 | |
jjg@946 | 456 | @Override |
jjg@946 | 457 | public Modifier getAccessLevel() { |
jjg@946 | 458 | throwUserExceptionIfNeeded(method, "getAccessLevel"); |
jjg@946 | 459 | return super.getAccessLevel(); |
jjg@946 | 460 | } |
jjg@946 | 461 | |
jjg@946 | 462 | @Override |
jjg@946 | 463 | public URI toUri() { |
jjg@946 | 464 | throwUserExceptionIfNeeded(method, "toUri"); |
jjg@946 | 465 | return super.toUri(); |
jjg@946 | 466 | } |
jjg@946 | 467 | |
jjg@946 | 468 | @Override |
jjg@946 | 469 | public String getName() { |
jjg@946 | 470 | throwUserExceptionIfNeeded(method, "getName"); |
jjg@946 | 471 | return super.getName(); |
jjg@946 | 472 | } |
jjg@946 | 473 | |
jjg@946 | 474 | @Override |
jjg@946 | 475 | public InputStream openInputStream() throws IOException { |
jjg@946 | 476 | throwUserExceptionIfNeeded(method, "openInputStream"); |
jjg@946 | 477 | return super.openInputStream(); |
jjg@946 | 478 | } |
jjg@946 | 479 | |
jjg@946 | 480 | @Override |
jjg@946 | 481 | public OutputStream openOutputStream() throws IOException { |
jjg@946 | 482 | throwUserExceptionIfNeeded(method, "openOutputStream"); |
jjg@946 | 483 | return super.openOutputStream(); |
jjg@946 | 484 | } |
jjg@946 | 485 | |
jjg@946 | 486 | @Override |
jjg@946 | 487 | public Reader openReader(boolean ignoreEncodingErrors) throws IOException { |
jjg@946 | 488 | throwUserExceptionIfNeeded(method, "openReader"); |
jjg@946 | 489 | return super.openReader(ignoreEncodingErrors); |
jjg@946 | 490 | } |
jjg@946 | 491 | |
jjg@946 | 492 | @Override |
jjg@946 | 493 | public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { |
jjg@946 | 494 | throwUserExceptionIfNeeded(method, "getCharContent"); |
jjg@946 | 495 | return super.getCharContent(ignoreEncodingErrors); |
jjg@946 | 496 | } |
jjg@946 | 497 | |
jjg@946 | 498 | @Override |
jjg@946 | 499 | public Writer openWriter() throws IOException { |
jjg@946 | 500 | throwUserExceptionIfNeeded(method, "openWriter"); |
jjg@946 | 501 | return super.openWriter(); |
jjg@946 | 502 | } |
jjg@946 | 503 | |
jjg@946 | 504 | @Override |
jjg@946 | 505 | public long getLastModified() { |
jjg@946 | 506 | throwUserExceptionIfNeeded(method, "getLastModified"); |
jjg@946 | 507 | return super.getLastModified(); |
jjg@946 | 508 | } |
jjg@946 | 509 | |
jjg@946 | 510 | @Override |
jjg@946 | 511 | public boolean delete() { |
jjg@946 | 512 | throwUserExceptionIfNeeded(method, "delete"); |
jjg@946 | 513 | return super.delete(); |
jjg@946 | 514 | } |
jjg@946 | 515 | |
jjg@946 | 516 | } |
jjg@946 | 517 | |
jjg@946 | 518 | static class UserProcessor extends JavacTestingAbstractProcessor { |
jjg@946 | 519 | Method method; |
jjg@946 | 520 | |
jjg@946 | 521 | UserProcessor(Method m) { |
jjg@946 | 522 | assert isDeclaredIn(m, Processor.class); |
jjg@946 | 523 | method = m; |
jjg@946 | 524 | } |
jjg@946 | 525 | |
jjg@946 | 526 | @Override |
jjg@946 | 527 | public Set<String> getSupportedOptions() { |
jjg@946 | 528 | throwUserExceptionIfNeeded(method, "getSupportedOptions"); |
jjg@946 | 529 | return super.getSupportedOptions(); |
jjg@946 | 530 | } |
jjg@946 | 531 | |
jjg@946 | 532 | @Override |
jjg@946 | 533 | public Set<String> getSupportedAnnotationTypes() { |
jjg@946 | 534 | throwUserExceptionIfNeeded(method, "getSupportedAnnotationTypes"); |
jjg@946 | 535 | return super.getSupportedAnnotationTypes(); |
jjg@946 | 536 | } |
jjg@946 | 537 | |
jjg@946 | 538 | @Override |
jjg@946 | 539 | public SourceVersion getSupportedSourceVersion() { |
jjg@946 | 540 | throwUserExceptionIfNeeded(method, "getSupportedSourceVersion"); |
jjg@946 | 541 | return super.getSupportedSourceVersion(); |
jjg@946 | 542 | } |
jjg@946 | 543 | |
jjg@946 | 544 | @Override |
jjg@946 | 545 | public void init(ProcessingEnvironment processingEnv) { |
jjg@946 | 546 | throwUserExceptionIfNeeded(method, "init"); |
jjg@946 | 547 | super.init(processingEnv); |
jjg@946 | 548 | } |
jjg@946 | 549 | |
jjg@946 | 550 | @Override |
jjg@946 | 551 | public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { |
jjg@946 | 552 | throwUserExceptionIfNeeded(method, "process"); |
jjg@946 | 553 | return true; |
jjg@946 | 554 | } |
jjg@946 | 555 | |
jjg@946 | 556 | @Override |
jjg@946 | 557 | public Iterable<? extends Completion> getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText) { |
jjg@946 | 558 | throwUserExceptionIfNeeded(method, "getCompletions"); |
jjg@946 | 559 | return super.getCompletions(element, annotation, member, userText); |
jjg@946 | 560 | } |
jjg@946 | 561 | } |
jjg@946 | 562 | |
jjg@946 | 563 | static class UserDiagnosticListener implements DiagnosticListener<JavaFileObject> { |
jjg@946 | 564 | Method method; |
jjg@946 | 565 | PrintWriter out; |
jjg@946 | 566 | |
jjg@946 | 567 | UserDiagnosticListener(Method m, PrintWriter out) { |
jjg@946 | 568 | assert isDeclaredIn(m, DiagnosticListener.class); |
jjg@946 | 569 | this.method = m; |
jjg@946 | 570 | this.out = out; |
jjg@946 | 571 | } |
jjg@946 | 572 | |
jjg@946 | 573 | @Override |
jjg@946 | 574 | public void report(Diagnostic<? extends JavaFileObject> diagnostic) { |
jjg@946 | 575 | throwUserExceptionIfNeeded(method, "report"); |
jjg@946 | 576 | out.println("report: " + diagnostic); |
jjg@946 | 577 | } |
jjg@946 | 578 | } |
jjg@946 | 579 | |
jjg@946 | 580 | static class UserTaskListener implements TaskListener { |
jjg@946 | 581 | Method method; |
jjg@946 | 582 | PrintWriter out; |
jjg@946 | 583 | |
jjg@946 | 584 | UserTaskListener(Method m, PrintWriter out) { |
jjg@946 | 585 | assert isDeclaredIn(m, TaskListener.class); |
jjg@946 | 586 | this.method = m; |
jjg@946 | 587 | this.out = out; |
jjg@946 | 588 | } |
jjg@946 | 589 | |
jjg@946 | 590 | @Override |
jjg@946 | 591 | public void started(TaskEvent e) { |
jjg@946 | 592 | throwUserExceptionIfNeeded(method, "started"); |
jjg@946 | 593 | out.println("started: " + e); |
jjg@946 | 594 | } |
jjg@946 | 595 | |
jjg@946 | 596 | @Override |
jjg@946 | 597 | public void finished(TaskEvent e) { |
jjg@946 | 598 | throwUserExceptionIfNeeded(method, "finished"); |
jjg@946 | 599 | out.println("finished: " + e); |
jjg@946 | 600 | } |
jjg@946 | 601 | } |
jjg@946 | 602 | |
jjg@946 | 603 | // </editor-fold> |
jjg@946 | 604 | } |