TestClientCodeWrapper.java revision 3573:c4a18ee691c4
178064Sume/* 262638Skris * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. 355505Sshin * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 455505Sshin * 555505Sshin * This code is free software; you can redistribute it and/or modify it 655505Sshin * under the terms of the GNU General Public License version 2 only, as 755505Sshin * published by the Free Software Foundation. 855505Sshin * 955505Sshin * This code is distributed in the hope that it will be useful, but WITHOUT 1055505Sshin * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1155505Sshin * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1255505Sshin * version 2 for more details (a copy is included in the LICENSE file that 1355505Sshin * accompanied this code). 1455505Sshin * 1555505Sshin * You should have received a copy of the GNU General Public License version 1655505Sshin * 2 along with this work; if not, write to the Free Software Foundation, 1755505Sshin * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1855505Sshin * 1955505Sshin * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2055505Sshin * or visit www.oracle.com if you need additional information or have any 2155505Sshin * questions. 2255505Sshin */ 2355505Sshin 2455505Sshin/* 2555505Sshin * @test 2655505Sshin * @bug 6437138 6482554 2755505Sshin * @summary JSR 199: Compiler doesn't diagnose crash in user code 2855505Sshin * @library ../lib 2955505Sshin * @modules jdk.compiler/com.sun.tools.javac.api 3055505Sshin * @build JavacTestingAbstractProcessor TestClientCodeWrapper 3155505Sshin * @run main TestClientCodeWrapper 3255505Sshin */ 3355505Sshin 3455505Sshinimport java.io.*; 3578064Sumeimport java.lang.reflect.Method; 3678064Sumeimport java.net.URI; 3755505Sshinimport java.util.*; 3855505Sshinimport javax.annotation.processing.*; 3955505Sshinimport javax.lang.model.*; 4078064Sumeimport javax.lang.model.element.*; 4155505Sshinimport javax.tools.*; 4255505Sshinimport javax.tools.JavaFileObject.Kind; 4355505Sshin 4455505Sshinimport com.sun.source.util.*; 4562638Skrisimport com.sun.tools.javac.api.*; 4655505Sshin 4762638Skrispublic class TestClientCodeWrapper extends JavacTestingAbstractProcessor { 4855505Sshin public static void main(String... args) throws Exception { 4955505Sshin new TestClientCodeWrapper().run(); 5055505Sshin } 5155505Sshin 5262638Skris /** 5362638Skris * Run a series of compilations, each with a different user-provided object 5462638Skris * configured to throw an exception when a specific method is invoked. 5555505Sshin * Then, verify the exception is thrown as expected. 5655505Sshin * 5755505Sshin * Some methods are not invoked from the compiler, and are excluded from the test. 5855505Sshin */ 5962638Skris void run() throws Exception { 6055505Sshin JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 6178064Sume try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { 62173412Skevlo defaultFileManager = fm; 63173412Skevlo 64173412Skevlo for (Method m: getMethodsExcept(JavaFileManager.class, 6555505Sshin "close", "getJavaFileForInput", "getModuleLocation", "getServiceLoader")) { 6655505Sshin test(m); 6755505Sshin } 6855505Sshin 6955505Sshin for (Method m: getMethodsExcept(FileObject.class, "delete")) { 7055505Sshin test(m); 7155505Sshin } 7255505Sshin 7355505Sshin for (Method m: getMethods(JavaFileObject.class)) { 7455505Sshin test(m); 7555505Sshin } 7655505Sshin 7755505Sshin for (Method m: getMethodsExcept(Processor.class, "getCompletions")) { 7855505Sshin test(m); 7955505Sshin } 8055505Sshin 8155505Sshin for (Method m: DiagnosticListener.class.getDeclaredMethods()) { 8255505Sshin test(m); 8355505Sshin } 8455505Sshin 8555505Sshin for (Method m: TaskListener.class.getDeclaredMethods()) { 8655505Sshin test(m); 8755505Sshin } 8855505Sshin 8955505Sshin if (errors > 0) 9055505Sshin throw new Exception(errors + " errors occurred"); 9155505Sshin } 9255505Sshin } 9355505Sshin 9455505Sshin /** Get a sorted set of the methods declared on a class. */ 9555505Sshin Set<Method> getMethods(Class<?> clazz) { 9655505Sshin return getMethodsExcept(clazz, new String[0]); 9755505Sshin } 9855505Sshin 9955505Sshin /** Get a sorted set of the methods declared on a class, excluding 10055505Sshin * specified methods by name. */ 10155505Sshin Set<Method> getMethodsExcept(Class<?> clazz, String... exclude) { 10255505Sshin Set<Method> methods = new TreeSet<Method>(new Comparator<Method>() { 10355505Sshin public int compare(Method m1, Method m2) { 10455505Sshin return m1.toString().compareTo(m2.toString()); 10555505Sshin } 10655505Sshin }); 10755505Sshin Set<String> e = new HashSet<String>(Arrays.asList(exclude)); 10855505Sshin for (Method m: clazz.getDeclaredMethods()) { 10955505Sshin if (!e.contains(m.getName())) 11055505Sshin methods.add(m); 11155505Sshin } 11255505Sshin return methods; 11355505Sshin } 11455505Sshin 11555505Sshin /** 11655505Sshin * Test a method in a user supplied component, to verify javac's handling 11755505Sshin * of any exceptions thrown by that method. 11855505Sshin */ 11955505Sshin void test(Method m) throws Exception { 12055505Sshin testNum++; 12155505Sshin 12255505Sshin File extDirs = new File("empty-extdirs"); 12355505Sshin extDirs.mkdirs(); 12455505Sshin 12555505Sshin File testClasses = new File("test" + testNum); 12655505Sshin testClasses.mkdirs(); 12755505Sshin defaultFileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(testClasses)); 12855505Sshin 12955505Sshin System.err.println("test " + testNum + ": " 13055505Sshin + m.getDeclaringClass().getSimpleName() + "." + m.getName()); 13155505Sshin 13255505Sshin StringWriter sw = new StringWriter(); 13355505Sshin PrintWriter pw = new PrintWriter(sw); 13455505Sshin 13555505Sshin List<String> javacOptions = Arrays.asList( 13655505Sshin "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", 13755505Sshin "-extdirs", extDirs.getPath(), // for use by filemanager handleOption 13855505Sshin "-processor", TestClientCodeWrapper.class.getName() 13955505Sshin ); 14055505Sshin 14155505Sshin List<String> classes = Collections.emptyList(); 14255505Sshin 14355505Sshin JavacTool tool = JavacTool.create(); 14455505Sshin try { 14555505Sshin JavacTask task = tool.getTask(pw, 14655505Sshin getFileManager(m, defaultFileManager), 14755505Sshin getDiagnosticListener(m, pw), 14855505Sshin javacOptions, 14955505Sshin classes, 15055505Sshin getCompilationUnits(m)); 15155505Sshin 15255505Sshin if (isDeclaredIn(m, Processor.class)) 15355505Sshin task.setProcessors(getProcessors(m)); 15455505Sshin 15555505Sshin if (isDeclaredIn(m, TaskListener.class)) 15655505Sshin task.setTaskListener(getTaskListener(m, pw)); 15755505Sshin 15855505Sshin boolean ok = task.call(); 15955505Sshin error("compilation " + (ok ? "succeeded" : "failed") + " unexpectedly"); 16055505Sshin } catch (RuntimeException e) { 16155505Sshin System.err.println("caught " + e); 16255505Sshin if (e.getClass() == RuntimeException.class) { 16355505Sshin Throwable cause = e.getCause(); 16455505Sshin if (cause instanceof UserError) { 16555505Sshin String expect = m.getName(); 16655505Sshin String found = cause.getMessage(); 16755505Sshin checkEqual("exception messaqe", expect, found); 16855505Sshin } else { 16955505Sshin cause.printStackTrace(System.err); 17055505Sshin error("Unexpected exception: " + cause); 17155505Sshin } 17255505Sshin } else { 17355505Sshin e.printStackTrace(System.err); 17455505Sshin error("Unexpected exception: " + e); 17555505Sshin } 17655505Sshin } 17755505Sshin 17855505Sshin pw.close(); 17955505Sshin String out = sw.toString(); 18055505Sshin System.err.println(out); 18155505Sshin } 18255505Sshin 18355505Sshin /** Get a file manager to use for the test compilation. */ 18455505Sshin JavaFileManager getFileManager(Method m, JavaFileManager defaultFileManager) { 18555505Sshin return isDeclaredIn(m, JavaFileManager.class, FileObject.class, JavaFileObject.class) 18655505Sshin ? new UserFileManager(m, defaultFileManager) 18755505Sshin : defaultFileManager; 18855505Sshin } 18955505Sshin 19055505Sshin /** Get a diagnostic listener to use for the test compilation. */ 19155505Sshin DiagnosticListener<JavaFileObject> getDiagnosticListener(Method m, PrintWriter out) { 19255505Sshin return isDeclaredIn(m, DiagnosticListener.class) 19355505Sshin ? new UserDiagnosticListener(m, out) 19455505Sshin : null; 19555505Sshin } 19655505Sshin 19755505Sshin /** Get a set of file objects to use for the test compilation. */ 19855505Sshin Iterable<? extends JavaFileObject> getCompilationUnits(Method m) { 19955505Sshin File testSrc = new File(System.getProperty("test.src")); 20055505Sshin File thisSrc = new File(testSrc, TestClientCodeWrapper.class.getName() + ".java"); 20155505Sshin Iterable<? extends JavaFileObject> files = defaultFileManager.getJavaFileObjects(thisSrc); 20255505Sshin if (isDeclaredIn(m, FileObject.class, JavaFileObject.class)) 20355505Sshin return Arrays.asList(new UserFileObject(m, files.iterator().next())); 20455505Sshin else 20555505Sshin return files; 20655505Sshin } 20755505Sshin 20855505Sshin /** Get a set of annotation processors to use for the test compilation. */ 20955505Sshin Iterable<? extends Processor> getProcessors(Method m) { 21055505Sshin return Arrays.asList(new UserProcessor(m)); 21155505Sshin } 21255505Sshin 21355505Sshin /** Get a task listener to use for the test compilation. */ 21455505Sshin TaskListener getTaskListener(Method m, PrintWriter out) { 21555505Sshin return new UserTaskListener(m, out); 21655505Sshin } 21755505Sshin 21855505Sshin /** Check if two values are .equal, and report an error if not. */ 21955505Sshin <T> void checkEqual(String label, T expect, T found) { 22055505Sshin if (!expect.equals(found)) 22155505Sshin error("Unexpected value for " + label + ": " + found + "; expected: " + expect); 22255505Sshin } 22355505Sshin 22455505Sshin /** Report an error. */ 22555505Sshin void error(String msg) { 22662638Skris System.err.println("Error: " + msg); 22762638Skris errors++; 22862638Skris } 22962638Skris 23062638Skris /** Check if a method is declared in any of a set of classes */ 23162638Skris static boolean isDeclaredIn(Method m, Class<?>... classes) { 23262638Skris Class<?> dc = m.getDeclaringClass(); 23362638Skris for (Class<?> c: classes) { 23462638Skris if (c == dc) return true; 23555505Sshin } 23655505Sshin return false; 23755505Sshin } 23855505Sshin 23955505Sshin /** Throw an intentional error if the method has a given name. */ 24055505Sshin static void throwUserExceptionIfNeeded(Method m, String name) { 24155505Sshin if (m != null && m.getName().equals(name)) 24255505Sshin throw new UserError(name); 24355505Sshin } 24455505Sshin 24555505Sshin StandardJavaFileManager defaultFileManager; 24655505Sshin int testNum; 24755505Sshin int errors; 24855505Sshin 24955505Sshin //-------------------------------------------------------------------------- 25055505Sshin 25155505Sshin /** 25255505Sshin * Processor used to trigger use of methods not normally used by javac. 25355505Sshin */ 25455505Sshin @Override 25555505Sshin public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 25655505Sshin boolean firstRound = false; 25755505Sshin for (Element e: roundEnv.getRootElements()) { 258173412Skevlo if (e.getSimpleName().contentEquals(TestClientCodeWrapper.class.getSimpleName())) 25978064Sume firstRound = true; 26055505Sshin } 26155505Sshin if (firstRound) { 26278064Sume try { 26355505Sshin FileObject f1 = filer.getResource(StandardLocation.CLASS_PATH, "", 26455505Sshin TestClientCodeWrapper.class.getName() + ".java"); 26555505Sshin f1.openInputStream().close(); 26655505Sshin f1.openReader(false).close(); 26755505Sshin 26855505Sshin FileObject f2 = filer.createResource( 26955505Sshin StandardLocation.CLASS_OUTPUT, "", "f2.txt", (Element[]) null); 27055505Sshin f2.openOutputStream().close(); 27155505Sshin 27255505Sshin FileObject f3 = filer.createResource( 27355505Sshin StandardLocation.CLASS_OUTPUT, "", "f3.txt", (Element[]) null); 274 f3.openWriter().close(); 275 276 JavaFileObject f4 = filer.createSourceFile("f4", (Element[]) null); 277 f4.openWriter().close(); 278 f4.getNestingKind(); 279 f4.getAccessLevel(); 280 281 messager.printMessage(Diagnostic.Kind.NOTE, "informational note", 282 roundEnv.getRootElements().iterator().next()); 283 284 } catch (IOException e) { 285 throw new UserError(e); 286 } 287 } 288 return true; 289 } 290 291 //-------------------------------------------------------------------------- 292 293 // <editor-fold defaultstate="collapsed" desc="User classes"> 294 295 static class UserError extends Error { 296 private static final long serialVersionUID = 1L; 297 UserError(String msg) { 298 super(msg); 299 } 300 UserError(Throwable t) { 301 super(t); 302 } 303 } 304 305 static class UserFileManager extends ForwardingJavaFileManager<JavaFileManager> { 306 Method fileManagerMethod; 307 Method fileObjectMethod; 308 309 UserFileManager(Method m, JavaFileManager delegate) { 310 super(delegate); 311 if (isDeclaredIn(m, JavaFileManager.class)) { 312 fileManagerMethod = m; 313 } else if (isDeclaredIn(m, FileObject.class, JavaFileObject.class)) { 314 fileObjectMethod = m; 315 } else 316 assert false; 317 } 318 319 @Override 320 public ClassLoader getClassLoader(Location location) { 321 throwUserExceptionIfNeeded(fileManagerMethod, "getClassLoader"); 322 return super.getClassLoader(location); 323 } 324 325 @Override 326 public <S> ServiceLoader getServiceLoader(Location location, Class<S> service) throws IOException { 327 throwUserExceptionIfNeeded(fileManagerMethod, "getServiceLoader"); 328 return super.getServiceLoader(location, service); 329 } 330 331 @Override 332 public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException { 333 throwUserExceptionIfNeeded(fileManagerMethod, "list"); 334 return wrap(super.list(location, packageName, kinds, recurse)); 335 } 336 337 @Override 338 public String inferBinaryName(Location location, JavaFileObject file) { 339 throwUserExceptionIfNeeded(fileManagerMethod, "inferBinaryName"); 340 return super.inferBinaryName(location, unwrap(file)); 341 } 342 343 @Override 344 public boolean isSameFile(FileObject a, FileObject b) { 345 throwUserExceptionIfNeeded(fileManagerMethod, "isSameFile"); 346 return super.isSameFile(unwrap(a), unwrap(b)); 347 } 348 349 @Override 350 public boolean handleOption(String current, Iterator<String> remaining) { 351 throwUserExceptionIfNeeded(fileManagerMethod, "handleOption"); 352 return super.handleOption(current, remaining); 353 } 354 355 @Override 356 public boolean hasLocation(Location location) { 357 throwUserExceptionIfNeeded(fileManagerMethod, "hasLocation"); 358 return super.hasLocation(location); 359 } 360 361 @Override 362 public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException { 363 throwUserExceptionIfNeeded(fileManagerMethod, "getJavaFileForInput"); 364 return wrap(super.getJavaFileForInput(location, className, kind)); 365 } 366 367 @Override 368 public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException { 369 throwUserExceptionIfNeeded(fileManagerMethod, "getJavaFileForOutput"); 370 return wrap(super.getJavaFileForOutput(location, className, kind, sibling)); 371 } 372 373 @Override 374 public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException { 375 throwUserExceptionIfNeeded(fileManagerMethod, "getFileForInput"); 376 return wrap(super.getFileForInput(location, packageName, relativeName)); 377 } 378 379 @Override 380 public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException { 381 throwUserExceptionIfNeeded(fileManagerMethod, "getFileForOutput"); 382 return wrap(super.getFileForOutput(location, packageName, relativeName, sibling)); 383 } 384 385 @Override 386 public void flush() throws IOException { 387 throwUserExceptionIfNeeded(fileManagerMethod, "flush"); 388 super.flush(); 389 } 390 391 @Override 392 public void close() throws IOException { 393 throwUserExceptionIfNeeded(fileManagerMethod, "close"); 394 super.close(); 395 } 396 397 @Override 398 public int isSupportedOption(String option) { 399 throwUserExceptionIfNeeded(fileManagerMethod, "isSupportedOption"); 400 return super.isSupportedOption(option); 401 } 402 403 @Override 404 public Location getModuleLocation(Location location, String moduleName) throws IOException { 405 throwUserExceptionIfNeeded(fileManagerMethod, "getModuleLocation"); 406 return super.getModuleLocation(location, moduleName); 407 } 408 409 @Override 410 public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException { 411 throwUserExceptionIfNeeded(fileManagerMethod, "getModuleLocation"); 412 return super.getModuleLocation(location, fo, pkgName); 413 } 414 415 @Override 416 public String inferModuleName(Location location) throws IOException { 417 throwUserExceptionIfNeeded(fileManagerMethod, "inferModuleName"); 418 return super.inferModuleName(location); 419 } 420 421 @Override 422 public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException { 423 throwUserExceptionIfNeeded(fileManagerMethod, "listModuleLocations"); 424 return super.listModuleLocations(location); 425 } 426 427 public FileObject wrap(FileObject fo) { 428 if (fileObjectMethod == null || fo == null) 429 return fo; 430 return new UserFileObject(fileObjectMethod, (JavaFileObject)fo); 431 } 432 433 FileObject unwrap(FileObject fo) { 434 if (fo instanceof UserFileObject) 435 return ((UserFileObject) fo).unwrap(); 436 else 437 return fo; 438 } 439 440 public JavaFileObject wrap(JavaFileObject fo) { 441 if (fileObjectMethod == null || fo == null) 442 return fo; 443 return new UserFileObject(fileObjectMethod, fo); 444 } 445 446 public Iterable<JavaFileObject> wrap(Iterable<? extends JavaFileObject> list) { 447 List<JavaFileObject> wrapped = new ArrayList<JavaFileObject>(); 448 for (JavaFileObject fo : list) 449 wrapped.add(wrap(fo)); 450 return Collections.unmodifiableList(wrapped); 451 } 452 453 JavaFileObject unwrap(JavaFileObject fo) { 454 if (fo instanceof UserFileObject) 455 return ((UserFileObject) fo).unwrap(); 456 else 457 return fo; 458 } 459 } 460 461 static class UserFileObject extends ForwardingJavaFileObject<JavaFileObject> { 462 Method method; 463 464 UserFileObject(Method m, JavaFileObject delegate) { 465 super(delegate); 466 assert isDeclaredIn(m, FileObject.class, JavaFileObject.class); 467 this.method = m; 468 } 469 470 JavaFileObject unwrap() { 471 return fileObject; 472 } 473 474 @Override 475 public Kind getKind() { 476 throwUserExceptionIfNeeded(method, "getKind"); 477 return super.getKind(); 478 } 479 480 @Override 481 public boolean isNameCompatible(String simpleName, Kind kind) { 482 throwUserExceptionIfNeeded(method, "isNameCompatible"); 483 return super.isNameCompatible(simpleName, kind); 484 } 485 486 @Override 487 public NestingKind getNestingKind() { 488 throwUserExceptionIfNeeded(method, "getNestingKind"); 489 return super.getNestingKind(); 490 } 491 492 @Override 493 public Modifier getAccessLevel() { 494 throwUserExceptionIfNeeded(method, "getAccessLevel"); 495 return super.getAccessLevel(); 496 } 497 498 @Override 499 public URI toUri() { 500 throwUserExceptionIfNeeded(method, "toUri"); 501 return super.toUri(); 502 } 503 504 @Override 505 public String getName() { 506 throwUserExceptionIfNeeded(method, "getName"); 507 return super.getName(); 508 } 509 510 @Override 511 public InputStream openInputStream() throws IOException { 512 throwUserExceptionIfNeeded(method, "openInputStream"); 513 return super.openInputStream(); 514 } 515 516 @Override 517 public OutputStream openOutputStream() throws IOException { 518 throwUserExceptionIfNeeded(method, "openOutputStream"); 519 return super.openOutputStream(); 520 } 521 522 @Override 523 public Reader openReader(boolean ignoreEncodingErrors) throws IOException { 524 throwUserExceptionIfNeeded(method, "openReader"); 525 return super.openReader(ignoreEncodingErrors); 526 } 527 528 @Override 529 public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { 530 throwUserExceptionIfNeeded(method, "getCharContent"); 531 return super.getCharContent(ignoreEncodingErrors); 532 } 533 534 @Override 535 public Writer openWriter() throws IOException { 536 throwUserExceptionIfNeeded(method, "openWriter"); 537 return super.openWriter(); 538 } 539 540 @Override 541 public long getLastModified() { 542 throwUserExceptionIfNeeded(method, "getLastModified"); 543 return super.getLastModified(); 544 } 545 546 @Override 547 public boolean delete() { 548 throwUserExceptionIfNeeded(method, "delete"); 549 return super.delete(); 550 } 551 552 } 553 554 static class UserProcessor extends JavacTestingAbstractProcessor { 555 Method method; 556 557 UserProcessor(Method m) { 558 assert isDeclaredIn(m, Processor.class); 559 method = m; 560 } 561 562 @Override 563 public Set<String> getSupportedOptions() { 564 throwUserExceptionIfNeeded(method, "getSupportedOptions"); 565 return super.getSupportedOptions(); 566 } 567 568 @Override 569 public Set<String> getSupportedAnnotationTypes() { 570 throwUserExceptionIfNeeded(method, "getSupportedAnnotationTypes"); 571 return super.getSupportedAnnotationTypes(); 572 } 573 574 @Override 575 public SourceVersion getSupportedSourceVersion() { 576 throwUserExceptionIfNeeded(method, "getSupportedSourceVersion"); 577 return super.getSupportedSourceVersion(); 578 } 579 580 @Override 581 public void init(ProcessingEnvironment processingEnv) { 582 throwUserExceptionIfNeeded(method, "init"); 583 super.init(processingEnv); 584 } 585 586 @Override 587 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 588 throwUserExceptionIfNeeded(method, "process"); 589 return true; 590 } 591 592 @Override 593 public Iterable<? extends Completion> getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText) { 594 throwUserExceptionIfNeeded(method, "getCompletions"); 595 return super.getCompletions(element, annotation, member, userText); 596 } 597 } 598 599 static class UserDiagnosticListener implements DiagnosticListener<JavaFileObject> { 600 Method method; 601 PrintWriter out; 602 603 UserDiagnosticListener(Method m, PrintWriter out) { 604 assert isDeclaredIn(m, DiagnosticListener.class); 605 this.method = m; 606 this.out = out; 607 } 608 609 @Override 610 public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 611 throwUserExceptionIfNeeded(method, "report"); 612 out.println("report: " + diagnostic); 613 } 614 } 615 616 static class UserTaskListener implements TaskListener { 617 Method method; 618 PrintWriter out; 619 620 UserTaskListener(Method m, PrintWriter out) { 621 assert isDeclaredIn(m, TaskListener.class); 622 this.method = m; 623 this.out = out; 624 } 625 626 @Override 627 public void started(TaskEvent e) { 628 throwUserExceptionIfNeeded(method, "started"); 629 out.println("started: " + e); 630 } 631 632 @Override 633 public void finished(TaskEvent e) { 634 throwUserExceptionIfNeeded(method, "finished"); 635 out.println("finished: " + e); 636 } 637 } 638 639 // </editor-fold> 640} 641