1 /*
   2  * Copyright (c) 2011, 2017, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.api;
  27 
  28 import java.io.File;
  29 import java.io.IOException;
  30 import java.io.InputStream;
  31 import java.io.OutputStream;
  32 import java.io.Reader;
  33 import java.io.Writer;
  34 import java.lang.annotation.ElementType;
  35 import java.lang.annotation.Retention;
  36 import java.lang.annotation.RetentionPolicy;
  37 import java.lang.annotation.Target;
  38 import java.net.URI;
  39 import java.nio.file.Path;
  40 import java.util.ArrayList;
  41 import java.util.Collection;
  42 import java.util.Collections;
  43 import java.util.HashMap;
  44 import java.util.Iterator;
  45 import java.util.List;
  46 import java.util.Locale;
  47 import java.util.Map;
  48 import java.util.Objects;
  49 import java.util.Set;
  50 
  51 import javax.lang.model.element.Modifier;
  52 import javax.lang.model.element.NestingKind;
  53 import javax.tools.Diagnostic;
  54 import javax.tools.DiagnosticListener;
  55 import javax.tools.FileObject;
  56 import javax.tools.JavaFileManager;
  57 import javax.tools.JavaFileManager.Location;
  58 import javax.tools.JavaFileObject;
  59 import javax.tools.JavaFileObject.Kind;
  60 import javax.tools.StandardJavaFileManager;
  61 
  62 import com.sun.source.util.TaskEvent;
  63 import com.sun.source.util.TaskListener;
  64 import com.sun.tools.javac.util.ClientCodeException;
  65 import com.sun.tools.javac.util.Context;
  66 import com.sun.tools.javac.util.DefinedBy;
  67 import com.sun.tools.javac.util.DefinedBy.Api;
  68 import com.sun.tools.javac.util.JCDiagnostic;
  69 
  70 /**
  71  *  Wrap objects to enable unchecked exceptions to be caught and handled.
  72  *
  73  *  For each method, exceptions are handled as follows:
  74  *  <ul>
  75  *  <li>Checked exceptions are left alone and propogate upwards in the
  76  *      obvious way, since they are an expected aspect of the method's
  77  *      specification.
  78  *  <li>Unchecked exceptions which have already been caught and wrapped in
  79  *      ClientCodeException are left alone to continue propogating upwards.
  80  *  <li>All other unchecked exceptions (i.e. subtypes of RuntimeException
  81  *      and Error) and caught, and rethrown as a ClientCodeException with
  82  *      its cause set to the original exception.
  83  *  </ul>
  84  *
  85  *  The intent is that ClientCodeException can be caught at an appropriate point
  86  *  in the program and can be distinguished from any unanticipated unchecked
  87  *  exceptions arising in the main body of the code (i.e. bugs.) When the
  88  *  ClientCodeException has been caught, either a suitable message can be
  89  *  generated, or if appropriate, the original cause can be rethrown.
  90  *
  91  *  <p><b>This is NOT part of any supported API.
  92  *  If you write code that depends on this, you do so at your own risk.
  93  *  This code and its internal interfaces are subject to change or
  94  *  deletion without notice.</b>
  95  */
  96 public class ClientCodeWrapper {
  97     @Retention(RetentionPolicy.RUNTIME)
  98     @Target(ElementType.TYPE)
  99     public @interface Trusted { }
 100 
 101     public static ClientCodeWrapper instance(Context context) {
 102         ClientCodeWrapper instance = context.get(ClientCodeWrapper.class);
 103         if (instance == null)
 104             instance = new ClientCodeWrapper(context);
 105         return instance;
 106     }
 107 
 108     /**
 109      * A map to cache the results of whether or not a specific classes can
 110      * be "trusted", and thus does not need to be wrapped.
 111      */
 112     Map<Class<?>, Boolean> trustedClasses;
 113 
 114     protected ClientCodeWrapper(Context context) {
 115         trustedClasses = new HashMap<>();
 116     }
 117 
 118     public JavaFileManager wrap(JavaFileManager fm) {
 119         if (isTrusted(fm))
 120             return fm;
 121         if (fm instanceof StandardJavaFileManager)
 122             return new WrappedStandardJavaFileManager((StandardJavaFileManager) fm);
 123         return new WrappedJavaFileManager(fm);
 124     }
 125 
 126     public FileObject wrap(FileObject fo) {
 127         if (fo == null || isTrusted(fo))
 128             return fo;
 129         return new WrappedFileObject(fo);
 130     }
 131 
 132     FileObject unwrap(FileObject fo) {
 133         if (fo instanceof WrappedFileObject)
 134             return ((WrappedFileObject) fo).clientFileObject;
 135         else
 136             return fo;
 137     }
 138 
 139     public JavaFileObject wrap(JavaFileObject fo) {
 140         if (fo == null || isTrusted(fo))
 141             return fo;
 142         return new WrappedJavaFileObject(fo);
 143     }
 144 
 145     public Iterable<JavaFileObject> wrapJavaFileObjects(Iterable<? extends JavaFileObject> list) {
 146         List<JavaFileObject> wrapped = new ArrayList<>();
 147         for (JavaFileObject fo : list)
 148             wrapped.add(wrap(fo));
 149         return Collections.unmodifiableList(wrapped);
 150     }
 151 
 152     JavaFileObject unwrap(JavaFileObject fo) {
 153         if (fo instanceof WrappedJavaFileObject)
 154             return ((JavaFileObject) ((WrappedJavaFileObject) fo).clientFileObject);
 155         else
 156             return fo;
 157     }
 158 
 159     public <T /*super JavaFileOject*/> DiagnosticListener<T> wrap(DiagnosticListener<T> dl) {
 160         if (isTrusted(dl))
 161             return dl;
 162         return new WrappedDiagnosticListener<>(dl);
 163     }
 164 
 165     TaskListener wrap(TaskListener tl) {
 166         if (isTrusted(tl))
 167             return tl;
 168         return new WrappedTaskListener(tl);
 169     }
 170 
 171     TaskListener unwrap(TaskListener l) {
 172         if (l instanceof WrappedTaskListener)
 173             return ((WrappedTaskListener) l).clientTaskListener;
 174         else
 175             return l;
 176     }
 177 
 178     Collection<TaskListener> unwrap(Collection<? extends TaskListener> listeners) {
 179         Collection<TaskListener> c = new ArrayList<>(listeners.size());
 180         for (TaskListener l: listeners)
 181             c.add(unwrap(l));
 182         return c;
 183     }
 184 
 185     @SuppressWarnings("unchecked")
 186     private <T> Diagnostic<T> unwrap(final Diagnostic<T> diagnostic) {
 187         if (diagnostic instanceof JCDiagnostic) {
 188             JCDiagnostic d = (JCDiagnostic) diagnostic;
 189             return (Diagnostic<T>) new DiagnosticSourceUnwrapper(d);
 190         } else {
 191             return diagnostic;
 192         }
 193     }
 194 
 195     protected boolean isTrusted(Object o) {
 196         Class<?> c = o.getClass();
 197         Boolean trusted = trustedClasses.get(c);
 198         if (trusted == null) {
 199             trusted = c.getName().startsWith("com.sun.tools.javac.")
 200                     || c.isAnnotationPresent(Trusted.class);
 201             trustedClasses.put(c, trusted);
 202         }
 203         return trusted;
 204     }
 205 
 206     private String wrappedToString(Class<?> wrapperClass, Object wrapped) {
 207         return wrapperClass.getSimpleName() + "[" + wrapped + "]";
 208     }
 209 
 210     // <editor-fold defaultstate="collapsed" desc="Wrapper classes">
 211 
 212     protected class WrappedJavaFileManager implements JavaFileManager {
 213         protected JavaFileManager clientJavaFileManager;
 214         WrappedJavaFileManager(JavaFileManager clientJavaFileManager) {
 215             this.clientJavaFileManager = Objects.requireNonNull(clientJavaFileManager);
 216         }
 217 
 218         @Override @DefinedBy(Api.COMPILER)
 219         public ClassLoader getClassLoader(Location location) {
 220             try {
 221                 return clientJavaFileManager.getClassLoader(location);
 222             } catch (ClientCodeException e) {
 223                 throw e;
 224             } catch (RuntimeException | Error e) {
 225                 throw new ClientCodeException(e);
 226             }
 227         }
 228 
 229         @Override @DefinedBy(Api.COMPILER)
 230         public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
 231             try {
 232                 return wrapJavaFileObjects(clientJavaFileManager.list(location, packageName, kinds, recurse));
 233             } catch (ClientCodeException e) {
 234                 throw e;
 235             } catch (RuntimeException | Error e) {
 236                 throw new ClientCodeException(e);
 237             }
 238         }
 239 
 240         @Override @DefinedBy(Api.COMPILER)
 241         public String inferBinaryName(Location location, JavaFileObject file) {
 242             try {
 243                 return clientJavaFileManager.inferBinaryName(location, unwrap(file));
 244             } catch (ClientCodeException e) {
 245                 throw e;
 246             } catch (RuntimeException | Error e) {
 247                 throw new ClientCodeException(e);
 248             }
 249         }
 250 
 251         @Override @DefinedBy(Api.COMPILER)
 252         public boolean isSameFile(FileObject a, FileObject b) {
 253             try {
 254                 return clientJavaFileManager.isSameFile(unwrap(a), unwrap(b));
 255             } catch (ClientCodeException e) {
 256                 throw e;
 257             } catch (RuntimeException | Error e) {
 258                 throw new ClientCodeException(e);
 259             }
 260         }
 261 
 262         @Override @DefinedBy(Api.COMPILER)
 263         public boolean handleOption(String current, Iterator<String> remaining) {
 264             try {
 265                 return clientJavaFileManager.handleOption(current, remaining);
 266             } catch (ClientCodeException e) {
 267                 throw e;
 268             } catch (RuntimeException | Error e) {
 269                 throw new ClientCodeException(e);
 270             }
 271         }
 272 
 273         @Override @DefinedBy(Api.COMPILER)
 274         public boolean hasLocation(Location location) {
 275             try {
 276                 return clientJavaFileManager.hasLocation(location);
 277             } catch (ClientCodeException e) {
 278                 throw e;
 279             } catch (RuntimeException | Error e) {
 280                 throw new ClientCodeException(e);
 281             }
 282         }
 283 
 284         @Override @DefinedBy(Api.COMPILER)
 285         public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
 286             try {
 287                 return wrap(clientJavaFileManager.getJavaFileForInput(location, className, kind));
 288             } catch (ClientCodeException e) {
 289                 throw e;
 290             } catch (RuntimeException | Error e) {
 291                 throw new ClientCodeException(e);
 292             }
 293         }
 294 
 295         @Override @DefinedBy(Api.COMPILER)
 296         public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
 297             try {
 298                 return wrap(clientJavaFileManager.getJavaFileForOutput(location, className, kind, unwrap(sibling)));
 299             } catch (ClientCodeException e) {
 300                 throw e;
 301             } catch (RuntimeException | Error e) {
 302                 throw new ClientCodeException(e);
 303             }
 304         }
 305 
 306         @Override @DefinedBy(Api.COMPILER)
 307         public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
 308             try {
 309                 return wrap(clientJavaFileManager.getFileForInput(location, packageName, relativeName));
 310             } catch (ClientCodeException e) {
 311                 throw e;
 312             } catch (RuntimeException | Error e) {
 313                 throw new ClientCodeException(e);
 314             }
 315         }
 316 
 317         @Override @DefinedBy(Api.COMPILER)
 318         public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException {
 319             try {
 320                 return wrap(clientJavaFileManager.getFileForOutput(location, packageName, relativeName, unwrap(sibling)));
 321             } catch (ClientCodeException e) {
 322                 throw e;
 323             } catch (RuntimeException | Error e) {
 324                 throw new ClientCodeException(e);
 325             }
 326         }
 327 
 328         @Override @DefinedBy(Api.COMPILER)
 329         public boolean contains(Location location, FileObject file) throws IOException {
 330             try {
 331                 return clientJavaFileManager.contains(location, unwrap(file));
 332             } catch (ClientCodeException e) {
 333                 throw e;
 334             } catch (RuntimeException | Error e) {
 335                 throw new ClientCodeException(e);
 336             }
 337         }
 338 
 339         @Override @DefinedBy(Api.COMPILER)
 340         public void flush() throws IOException {
 341             try {
 342                 clientJavaFileManager.flush();
 343             } catch (ClientCodeException e) {
 344                 throw e;
 345             } catch (RuntimeException | Error e) {
 346                 throw new ClientCodeException(e);
 347             }
 348         }
 349 
 350         @Override @DefinedBy(Api.COMPILER)
 351         public void close() throws IOException {
 352             try {
 353                 clientJavaFileManager.close();
 354             } catch (ClientCodeException e) {
 355                 throw e;
 356             } catch (RuntimeException | Error e) {
 357                 throw new ClientCodeException(e);
 358             }
 359         }
 360 
 361         @Override @DefinedBy(Api.COMPILER)
 362         public Location getLocationForModule(Location location, String moduleName) throws IOException {
 363             try {
 364                 return clientJavaFileManager.getLocationForModule(location, moduleName);
 365             } catch (ClientCodeException e) {
 366                 throw e;
 367             } catch (RuntimeException | Error e) {
 368                 throw new ClientCodeException(e);
 369             }
 370         }
 371 
 372         @Override @DefinedBy(Api.COMPILER)
 373         public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
 374             try {
 375                 return clientJavaFileManager.getLocationForModule(location, unwrap(fo));
 376             } catch (ClientCodeException e) {
 377                 throw e;
 378             } catch (RuntimeException | Error e) {
 379                 throw new ClientCodeException(e);
 380             }
 381         }
 382 
 383         @Override @DefinedBy(Api.COMPILER)
 384         public String inferModuleName(Location location) throws IOException {
 385             try {
 386                 return clientJavaFileManager.inferModuleName(location);
 387             } catch (ClientCodeException e) {
 388                 throw e;
 389             } catch (RuntimeException | Error e) {
 390                 throw new ClientCodeException(e);
 391             }
 392         }
 393 
 394         @Override @DefinedBy(Api.COMPILER)
 395         public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
 396             try {
 397                 return clientJavaFileManager.listLocationsForModules(location);
 398             } catch (ClientCodeException e) {
 399                 throw e;
 400             } catch (RuntimeException | Error e) {
 401                 throw new ClientCodeException(e);
 402             }
 403         }
 404 
 405         @Override @DefinedBy(Api.COMPILER)
 406         public int isSupportedOption(String option) {
 407             try {
 408                 return clientJavaFileManager.isSupportedOption(option);
 409             } catch (ClientCodeException e) {
 410                 throw e;
 411             } catch (RuntimeException | Error e) {
 412                 throw new ClientCodeException(e);
 413             }
 414         }
 415 
 416         @Override
 417         public String toString() {
 418             return wrappedToString(getClass(), clientJavaFileManager);
 419         }
 420     }
 421 
 422     protected class WrappedStandardJavaFileManager extends WrappedJavaFileManager
 423             implements StandardJavaFileManager {
 424         WrappedStandardJavaFileManager(StandardJavaFileManager clientJavaFileManager) {
 425             super(clientJavaFileManager);
 426         }
 427 
 428         @Override @DefinedBy(Api.COMPILER)
 429         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
 430             try {
 431                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromFiles(files);
 432             } catch (ClientCodeException e) {
 433                 throw e;
 434             } catch (RuntimeException | Error e) {
 435                 throw new ClientCodeException(e);
 436             }
 437         }
 438 
 439         @Override @DefinedBy(Api.COMPILER)
 440         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(Collection<? extends Path> paths) {
 441             try {
 442                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromPaths(paths);
 443             } catch (ClientCodeException e) {
 444                 throw e;
 445             } catch (RuntimeException | Error e) {
 446                 throw new ClientCodeException(e);
 447             }
 448         }
 449 
 450         @Deprecated(since = "13")
 451         @Override @DefinedBy(Api.COMPILER)
 452         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(Iterable<? extends Path> paths) {
 453             try {
 454                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromPaths(paths);
 455             } catch (ClientCodeException e) {
 456                 throw e;
 457             } catch (RuntimeException | Error e) {
 458                 throw new ClientCodeException(e);
 459             }
 460         }
 461 
 462         @Override @DefinedBy(Api.COMPILER)
 463         public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
 464             try {
 465                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjects(files);
 466             } catch (ClientCodeException e) {
 467                 throw e;
 468             } catch (RuntimeException | Error e) {
 469                 throw new ClientCodeException(e);
 470             }
 471         }
 472 
 473         @Override @DefinedBy(Api.COMPILER)
 474         public Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths) {
 475             try {
 476                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjects(paths);
 477             } catch (ClientCodeException e) {
 478                 throw e;
 479             } catch (RuntimeException | Error e) {
 480                 throw new ClientCodeException(e);
 481             }
 482         }
 483 
 484         @Override @DefinedBy(Api.COMPILER)
 485         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
 486             try {
 487                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromStrings(names);
 488             } catch (ClientCodeException e) {
 489                 throw e;
 490             } catch (RuntimeException | Error e) {
 491                 throw new ClientCodeException(e);
 492             }
 493         }
 494 
 495         @Override @DefinedBy(Api.COMPILER)
 496         public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
 497             try {
 498                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjects(names);
 499             } catch (ClientCodeException e) {
 500                 throw e;
 501             } catch (RuntimeException | Error e) {
 502                 throw new ClientCodeException(e);
 503             }
 504         }
 505 
 506         @Override @DefinedBy(Api.COMPILER)
 507         public void setLocation(Location location, Iterable<? extends File> files) throws IOException {
 508             try {
 509                 ((StandardJavaFileManager)clientJavaFileManager).setLocation(location, files);
 510             } catch (ClientCodeException e) {
 511                 throw e;
 512             } catch (RuntimeException | Error e) {
 513                 throw new ClientCodeException(e);
 514             }
 515         }
 516 
 517         @Override @DefinedBy(Api.COMPILER)
 518         public void setLocationFromPaths(Location location, Collection<? extends Path> paths) throws IOException {
 519             try {
 520                 ((StandardJavaFileManager)clientJavaFileManager).setLocationFromPaths(location, paths);
 521             } catch (ClientCodeException e) {
 522                 throw e;
 523             } catch (RuntimeException | Error e) {
 524                 throw new ClientCodeException(e);
 525             }
 526         }
 527 
 528         @Override @DefinedBy(Api.COMPILER)
 529         public Iterable<? extends File> getLocation(Location location) {
 530             try {
 531                 return ((StandardJavaFileManager)clientJavaFileManager).getLocation(location);
 532             } catch (ClientCodeException e) {
 533                 throw e;
 534             } catch (RuntimeException | Error e) {
 535                 throw new ClientCodeException(e);
 536             }
 537         }
 538 
 539         @Override @DefinedBy(Api.COMPILER)
 540         public Iterable<? extends Path> getLocationAsPaths(Location location) {
 541             try {
 542                 return ((StandardJavaFileManager)clientJavaFileManager).getLocationAsPaths(location);
 543             } catch (ClientCodeException e) {
 544                 throw e;
 545             } catch (RuntimeException | Error e) {
 546                 throw new ClientCodeException(e);
 547             }
 548         }
 549 
 550         @Override @DefinedBy(Api.COMPILER)
 551         public Path asPath(FileObject file) {
 552             try {
 553                 return ((StandardJavaFileManager)clientJavaFileManager).asPath(file);
 554             } catch (ClientCodeException e) {
 555                 throw e;
 556             } catch (RuntimeException | Error e) {
 557                 throw new ClientCodeException(e);
 558             }
 559         }
 560 
 561         @Override @DefinedBy(Api.COMPILER)
 562         public void setPathFactory(PathFactory f) {
 563             try {
 564                 ((StandardJavaFileManager)clientJavaFileManager).setPathFactory(f);
 565             } catch (ClientCodeException e) {
 566                 throw e;
 567             } catch (RuntimeException | Error e) {
 568                 throw new ClientCodeException(e);
 569             }
 570         }
 571     }
 572 
 573     protected class WrappedFileObject implements FileObject {
 574         protected FileObject clientFileObject;
 575         WrappedFileObject(FileObject clientFileObject) {
 576             this.clientFileObject = Objects.requireNonNull(clientFileObject);
 577         }
 578 
 579         @Override @DefinedBy(Api.COMPILER)
 580         public URI toUri() {
 581             try {
 582                 return clientFileObject.toUri();
 583             } catch (ClientCodeException e) {
 584                 throw e;
 585             } catch (RuntimeException | Error e) {
 586                 throw new ClientCodeException(e);
 587             }
 588         }
 589 
 590         @Override @DefinedBy(Api.COMPILER)
 591         public String getName() {
 592             try {
 593                 return clientFileObject.getName();
 594             } catch (ClientCodeException e) {
 595                 throw e;
 596             } catch (RuntimeException | Error e) {
 597                 throw new ClientCodeException(e);
 598             }
 599         }
 600 
 601         @Override @DefinedBy(Api.COMPILER)
 602         public InputStream openInputStream() throws IOException {
 603             try {
 604                 return clientFileObject.openInputStream();
 605             } catch (ClientCodeException e) {
 606                 throw e;
 607             } catch (RuntimeException | Error e) {
 608                 throw new ClientCodeException(e);
 609             }
 610         }
 611 
 612         @Override @DefinedBy(Api.COMPILER)
 613         public OutputStream openOutputStream() throws IOException {
 614             try {
 615                 return clientFileObject.openOutputStream();
 616             } catch (ClientCodeException e) {
 617                 throw e;
 618             } catch (RuntimeException | Error e) {
 619                 throw new ClientCodeException(e);
 620             }
 621         }
 622 
 623         @Override @DefinedBy(Api.COMPILER)
 624         public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
 625             try {
 626                 return clientFileObject.openReader(ignoreEncodingErrors);
 627             } catch (ClientCodeException e) {
 628                 throw e;
 629             } catch (RuntimeException | Error e) {
 630                 throw new ClientCodeException(e);
 631             }
 632         }
 633 
 634         @Override @DefinedBy(Api.COMPILER)
 635         public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
 636             try {
 637                 return clientFileObject.getCharContent(ignoreEncodingErrors);
 638             } catch (ClientCodeException e) {
 639                 throw e;
 640             } catch (RuntimeException | Error e) {
 641                 throw new ClientCodeException(e);
 642             }
 643         }
 644 
 645         @Override @DefinedBy(Api.COMPILER)
 646         public Writer openWriter() throws IOException {
 647             try {
 648                 return clientFileObject.openWriter();
 649             } catch (ClientCodeException e) {
 650                 throw e;
 651             } catch (RuntimeException | Error e) {
 652                 throw new ClientCodeException(e);
 653             }
 654         }
 655 
 656         @Override @DefinedBy(Api.COMPILER)
 657         public long getLastModified() {
 658             try {
 659                 return clientFileObject.getLastModified();
 660             } catch (ClientCodeException e) {
 661                 throw e;
 662             } catch (RuntimeException | Error e) {
 663                 throw new ClientCodeException(e);
 664             }
 665         }
 666 
 667         @Override @DefinedBy(Api.COMPILER)
 668         public boolean delete() {
 669             try {
 670                 return clientFileObject.delete();
 671             } catch (ClientCodeException e) {
 672                 throw e;
 673             } catch (RuntimeException | Error e) {
 674                 throw new ClientCodeException(e);
 675             }
 676         }
 677 
 678         @Override
 679         public String toString() {
 680             return wrappedToString(getClass(), clientFileObject);
 681         }
 682     }
 683 
 684     protected class WrappedJavaFileObject extends WrappedFileObject implements JavaFileObject {
 685         WrappedJavaFileObject(JavaFileObject clientJavaFileObject) {
 686             super(clientJavaFileObject);
 687         }
 688 
 689         @Override @DefinedBy(Api.COMPILER)
 690         public Kind getKind() {
 691             try {
 692                 return ((JavaFileObject)clientFileObject).getKind();
 693             } catch (ClientCodeException e) {
 694                 throw e;
 695             } catch (RuntimeException | Error e) {
 696                 throw new ClientCodeException(e);
 697             }
 698         }
 699 
 700         @Override @DefinedBy(Api.COMPILER)
 701         public boolean isNameCompatible(String simpleName, Kind kind) {
 702             try {
 703                 return ((JavaFileObject)clientFileObject).isNameCompatible(simpleName, kind);
 704             } catch (ClientCodeException e) {
 705                 throw e;
 706             } catch (RuntimeException | Error e) {
 707                 throw new ClientCodeException(e);
 708             }
 709         }
 710 
 711         @Override @DefinedBy(Api.COMPILER)
 712         public NestingKind getNestingKind() {
 713             try {
 714                 return ((JavaFileObject)clientFileObject).getNestingKind();
 715             } catch (ClientCodeException e) {
 716                 throw e;
 717             } catch (RuntimeException | Error e) {
 718                 throw new ClientCodeException(e);
 719             }
 720         }
 721 
 722         @Override @DefinedBy(Api.COMPILER)
 723         public Modifier getAccessLevel() {
 724             try {
 725                 return ((JavaFileObject)clientFileObject).getAccessLevel();
 726             } catch (ClientCodeException e) {
 727                 throw e;
 728             } catch (RuntimeException | Error e) {
 729                 throw new ClientCodeException(e);
 730             }
 731         }
 732 
 733         @Override
 734         public String toString() {
 735             return wrappedToString(getClass(), clientFileObject);
 736         }
 737     }
 738 
 739     protected class WrappedDiagnosticListener<T /*super JavaFileObject*/> implements DiagnosticListener<T> {
 740         protected DiagnosticListener<T> clientDiagnosticListener;
 741         WrappedDiagnosticListener(DiagnosticListener<T> clientDiagnosticListener) {
 742             this.clientDiagnosticListener = Objects.requireNonNull(clientDiagnosticListener);
 743         }
 744 
 745         @Override @DefinedBy(Api.COMPILER)
 746         public void report(Diagnostic<? extends T> diagnostic) {
 747             try {
 748                 clientDiagnosticListener.report(unwrap(diagnostic));
 749             } catch (ClientCodeException e) {
 750                 throw e;
 751             } catch (RuntimeException | Error e) {
 752                 throw new ClientCodeException(e);
 753             }
 754         }
 755 
 756         @Override
 757         public String toString() {
 758             return wrappedToString(getClass(), clientDiagnosticListener);
 759         }
 760     }
 761 
 762     public class DiagnosticSourceUnwrapper implements Diagnostic<JavaFileObject> {
 763         public final JCDiagnostic d;
 764 
 765         DiagnosticSourceUnwrapper(JCDiagnostic d) {
 766             this.d = d;
 767         }
 768 
 769         @Override @DefinedBy(Api.COMPILER)
 770         public Diagnostic.Kind getKind() {
 771             return d.getKind();
 772         }
 773 
 774         @Override @DefinedBy(Api.COMPILER)
 775         public JavaFileObject getSource() {
 776             return unwrap(d.getSource());
 777         }
 778 
 779         @Override @DefinedBy(Api.COMPILER)
 780         public long getPosition() {
 781             return d.getPosition();
 782         }
 783 
 784         @Override @DefinedBy(Api.COMPILER)
 785         public long getStartPosition() {
 786             return d.getStartPosition();
 787         }
 788 
 789         @Override @DefinedBy(Api.COMPILER)
 790         public long getEndPosition() {
 791             return d.getEndPosition();
 792         }
 793 
 794         @Override @DefinedBy(Api.COMPILER)
 795         public long getLineNumber() {
 796             return d.getLineNumber();
 797         }
 798 
 799         @Override @DefinedBy(Api.COMPILER)
 800         public long getColumnNumber() {
 801             return d.getColumnNumber();
 802         }
 803 
 804         @Override @DefinedBy(Api.COMPILER)
 805         public String getCode() {
 806             return d.getCode();
 807         }
 808 
 809         @Override @DefinedBy(Api.COMPILER)
 810         public String getMessage(Locale locale) {
 811             return d.getMessage(locale);
 812         }
 813 
 814         @Override
 815         public String toString() {
 816             return d.toString();
 817         }
 818     }
 819 
 820     protected class WrappedTaskListener implements TaskListener {
 821         protected TaskListener clientTaskListener;
 822         WrappedTaskListener(TaskListener clientTaskListener) {
 823             this.clientTaskListener = Objects.requireNonNull(clientTaskListener);
 824         }
 825 
 826         @Override @DefinedBy(Api.COMPILER_TREE)
 827         public void started(TaskEvent ev) {
 828             try {
 829                 clientTaskListener.started(ev);
 830             } catch (ClientCodeException e) {
 831                 throw e;
 832             } catch (RuntimeException | Error e) {
 833                 throw new ClientCodeException(e);
 834             }
 835         }
 836 
 837         @Override @DefinedBy(Api.COMPILER_TREE)
 838         public void finished(TaskEvent ev) {
 839             try {
 840                 clientTaskListener.finished(ev);
 841             } catch (ClientCodeException e) {
 842                 throw e;
 843             } catch (RuntimeException | Error e) {
 844                 throw new ClientCodeException(e);
 845             }
 846         }
 847 
 848         @Override
 849         public String toString() {
 850             return wrappedToString(getClass(), clientTaskListener);
 851         }
 852     }
 853 
 854     // </editor-fold>
 855 }