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 
instance(Context context)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 
ClientCodeWrapper(Context context)114     protected ClientCodeWrapper(Context context) {
115         trustedClasses = new HashMap<>();
116     }
117 
wrap(JavaFileManager fm)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 
wrap(FileObject fo)126     public FileObject wrap(FileObject fo) {
127         if (fo == null || isTrusted(fo))
128             return fo;
129         return new WrappedFileObject(fo);
130     }
131 
unwrap(FileObject fo)132     FileObject unwrap(FileObject fo) {
133         if (fo instanceof WrappedFileObject)
134             return ((WrappedFileObject) fo).clientFileObject;
135         else
136             return fo;
137     }
138 
wrap(JavaFileObject fo)139     public JavaFileObject wrap(JavaFileObject fo) {
140         if (fo == null || isTrusted(fo))
141             return fo;
142         return new WrappedJavaFileObject(fo);
143     }
144 
wrapJavaFileObjects(Iterable<? extends JavaFileObject> list)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 
unwrap(JavaFileObject fo)152     JavaFileObject unwrap(JavaFileObject fo) {
153         if (fo instanceof WrappedJavaFileObject)
154             return ((JavaFileObject) ((WrappedJavaFileObject) fo).clientFileObject);
155         else
156             return fo;
157     }
158 
wrap(DiagnosticListener<T> dl)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 
wrap(TaskListener tl)165     TaskListener wrap(TaskListener tl) {
166         if (isTrusted(tl))
167             return tl;
168         return new WrappedTaskListener(tl);
169     }
170 
unwrap(TaskListener l)171     TaskListener unwrap(TaskListener l) {
172         if (l instanceof WrappedTaskListener)
173             return ((WrappedTaskListener) l).clientTaskListener;
174         else
175             return l;
176     }
177 
unwrap(Collection<? extends TaskListener> listeners)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")
unwrap(final Diagnostic<T> diagnostic)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 
isTrusted(Object o)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 
wrappedToString(Class<?> wrapperClass, Object wrapped)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;
WrappedJavaFileManager(JavaFileManager clientJavaFileManager)214         WrappedJavaFileManager(JavaFileManager clientJavaFileManager) {
215             this.clientJavaFileManager = Objects.requireNonNull(clientJavaFileManager);
216         }
217 
218         @Override @DefinedBy(Api.COMPILER)
getClassLoader(Location location)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)
list(Location location, String packageName, Set<Kind> kinds, boolean recurse)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)
inferBinaryName(Location location, JavaFileObject file)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)
isSameFile(FileObject a, FileObject b)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)
handleOption(String current, Iterator<String> remaining)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)
hasLocation(Location location)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)
getJavaFileForInput(Location location, String className, Kind kind)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)
getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling)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)
getFileForInput(Location location, String packageName, String relativeName)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)
getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling)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)
contains(Location location, FileObject file)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)
flush()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)
close()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)
getLocationForModule(Location location, String moduleName)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)
getLocationForModule(Location location, JavaFileObject fo)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)
inferModuleName(Location location)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)
listLocationsForModules(Location location)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)
isSupportedOption(String option)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
toString()417         public String toString() {
418             return wrappedToString(getClass(), clientJavaFileManager);
419         }
420     }
421 
422     protected class WrappedStandardJavaFileManager extends WrappedJavaFileManager
423             implements StandardJavaFileManager {
WrappedStandardJavaFileManager(StandardJavaFileManager clientJavaFileManager)424         WrappedStandardJavaFileManager(StandardJavaFileManager clientJavaFileManager) {
425             super(clientJavaFileManager);
426         }
427 
428         @Override @DefinedBy(Api.COMPILER)
getJavaFileObjectsFromFiles(Iterable<? extends File> files)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)
getJavaFileObjectsFromPaths(Iterable<? extends Path> paths)440         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(Iterable<? 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         @Override @DefinedBy(Api.COMPILER)
getJavaFileObjects(File... files)451         public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
452             try {
453                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjects(files);
454             } catch (ClientCodeException e) {
455                 throw e;
456             } catch (RuntimeException | Error e) {
457                 throw new ClientCodeException(e);
458             }
459         }
460 
461         @Override @DefinedBy(Api.COMPILER)
getJavaFileObjects(Path... paths)462         public Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths) {
463             try {
464                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjects(paths);
465             } catch (ClientCodeException e) {
466                 throw e;
467             } catch (RuntimeException | Error e) {
468                 throw new ClientCodeException(e);
469             }
470         }
471 
472         @Override @DefinedBy(Api.COMPILER)
getJavaFileObjectsFromStrings(Iterable<String> names)473         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
474             try {
475                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromStrings(names);
476             } catch (ClientCodeException e) {
477                 throw e;
478             } catch (RuntimeException | Error e) {
479                 throw new ClientCodeException(e);
480             }
481         }
482 
483         @Override @DefinedBy(Api.COMPILER)
getJavaFileObjects(String... names)484         public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
485             try {
486                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjects(names);
487             } catch (ClientCodeException e) {
488                 throw e;
489             } catch (RuntimeException | Error e) {
490                 throw new ClientCodeException(e);
491             }
492         }
493 
494         @Override @DefinedBy(Api.COMPILER)
setLocation(Location location, Iterable<? extends File> files)495         public void setLocation(Location location, Iterable<? extends File> files) throws IOException {
496             try {
497                 ((StandardJavaFileManager)clientJavaFileManager).setLocation(location, files);
498             } catch (ClientCodeException e) {
499                 throw e;
500             } catch (RuntimeException | Error e) {
501                 throw new ClientCodeException(e);
502             }
503         }
504 
505         @Override @DefinedBy(Api.COMPILER)
setLocationFromPaths(Location location, Collection<? extends Path> paths)506         public void setLocationFromPaths(Location location, Collection<? extends Path> paths) throws IOException {
507             try {
508                 ((StandardJavaFileManager)clientJavaFileManager).setLocationFromPaths(location, paths);
509             } catch (ClientCodeException e) {
510                 throw e;
511             } catch (RuntimeException | Error e) {
512                 throw new ClientCodeException(e);
513             }
514         }
515 
516         @Override @DefinedBy(Api.COMPILER)
getLocation(Location location)517         public Iterable<? extends File> getLocation(Location location) {
518             try {
519                 return ((StandardJavaFileManager)clientJavaFileManager).getLocation(location);
520             } catch (ClientCodeException e) {
521                 throw e;
522             } catch (RuntimeException | Error e) {
523                 throw new ClientCodeException(e);
524             }
525         }
526 
527         @Override @DefinedBy(Api.COMPILER)
getLocationAsPaths(Location location)528         public Iterable<? extends Path> getLocationAsPaths(Location location) {
529             try {
530                 return ((StandardJavaFileManager)clientJavaFileManager).getLocationAsPaths(location);
531             } catch (ClientCodeException e) {
532                 throw e;
533             } catch (RuntimeException | Error e) {
534                 throw new ClientCodeException(e);
535             }
536         }
537 
538         @Override @DefinedBy(Api.COMPILER)
asPath(FileObject file)539         public Path asPath(FileObject file) {
540             try {
541                 return ((StandardJavaFileManager)clientJavaFileManager).asPath(file);
542             } catch (ClientCodeException e) {
543                 throw e;
544             } catch (RuntimeException | Error e) {
545                 throw new ClientCodeException(e);
546             }
547         }
548 
549         @Override @DefinedBy(Api.COMPILER)
setPathFactory(PathFactory f)550         public void setPathFactory(PathFactory f) {
551             try {
552                 ((StandardJavaFileManager)clientJavaFileManager).setPathFactory(f);
553             } catch (ClientCodeException e) {
554                 throw e;
555             } catch (RuntimeException | Error e) {
556                 throw new ClientCodeException(e);
557             }
558         }
559     }
560 
561     protected class WrappedFileObject implements FileObject {
562         protected FileObject clientFileObject;
WrappedFileObject(FileObject clientFileObject)563         WrappedFileObject(FileObject clientFileObject) {
564             this.clientFileObject = Objects.requireNonNull(clientFileObject);
565         }
566 
567         @Override @DefinedBy(Api.COMPILER)
toUri()568         public URI toUri() {
569             try {
570                 return clientFileObject.toUri();
571             } catch (ClientCodeException e) {
572                 throw e;
573             } catch (RuntimeException | Error e) {
574                 throw new ClientCodeException(e);
575             }
576         }
577 
578         @Override @DefinedBy(Api.COMPILER)
getName()579         public String getName() {
580             try {
581                 return clientFileObject.getName();
582             } catch (ClientCodeException e) {
583                 throw e;
584             } catch (RuntimeException | Error e) {
585                 throw new ClientCodeException(e);
586             }
587         }
588 
589         @Override @DefinedBy(Api.COMPILER)
openInputStream()590         public InputStream openInputStream() throws IOException {
591             try {
592                 return clientFileObject.openInputStream();
593             } catch (ClientCodeException e) {
594                 throw e;
595             } catch (RuntimeException | Error e) {
596                 throw new ClientCodeException(e);
597             }
598         }
599 
600         @Override @DefinedBy(Api.COMPILER)
openOutputStream()601         public OutputStream openOutputStream() throws IOException {
602             try {
603                 return clientFileObject.openOutputStream();
604             } catch (ClientCodeException e) {
605                 throw e;
606             } catch (RuntimeException | Error e) {
607                 throw new ClientCodeException(e);
608             }
609         }
610 
611         @Override @DefinedBy(Api.COMPILER)
openReader(boolean ignoreEncodingErrors)612         public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
613             try {
614                 return clientFileObject.openReader(ignoreEncodingErrors);
615             } catch (ClientCodeException e) {
616                 throw e;
617             } catch (RuntimeException | Error e) {
618                 throw new ClientCodeException(e);
619             }
620         }
621 
622         @Override @DefinedBy(Api.COMPILER)
getCharContent(boolean ignoreEncodingErrors)623         public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
624             try {
625                 return clientFileObject.getCharContent(ignoreEncodingErrors);
626             } catch (ClientCodeException e) {
627                 throw e;
628             } catch (RuntimeException | Error e) {
629                 throw new ClientCodeException(e);
630             }
631         }
632 
633         @Override @DefinedBy(Api.COMPILER)
openWriter()634         public Writer openWriter() throws IOException {
635             try {
636                 return clientFileObject.openWriter();
637             } catch (ClientCodeException e) {
638                 throw e;
639             } catch (RuntimeException | Error e) {
640                 throw new ClientCodeException(e);
641             }
642         }
643 
644         @Override @DefinedBy(Api.COMPILER)
getLastModified()645         public long getLastModified() {
646             try {
647                 return clientFileObject.getLastModified();
648             } catch (ClientCodeException e) {
649                 throw e;
650             } catch (RuntimeException | Error e) {
651                 throw new ClientCodeException(e);
652             }
653         }
654 
655         @Override @DefinedBy(Api.COMPILER)
delete()656         public boolean delete() {
657             try {
658                 return clientFileObject.delete();
659             } catch (ClientCodeException e) {
660                 throw e;
661             } catch (RuntimeException | Error e) {
662                 throw new ClientCodeException(e);
663             }
664         }
665 
666         @Override
toString()667         public String toString() {
668             return wrappedToString(getClass(), clientFileObject);
669         }
670     }
671 
672     protected class WrappedJavaFileObject extends WrappedFileObject implements JavaFileObject {
WrappedJavaFileObject(JavaFileObject clientJavaFileObject)673         WrappedJavaFileObject(JavaFileObject clientJavaFileObject) {
674             super(clientJavaFileObject);
675         }
676 
677         @Override @DefinedBy(Api.COMPILER)
getKind()678         public Kind getKind() {
679             try {
680                 return ((JavaFileObject)clientFileObject).getKind();
681             } catch (ClientCodeException e) {
682                 throw e;
683             } catch (RuntimeException | Error e) {
684                 throw new ClientCodeException(e);
685             }
686         }
687 
688         @Override @DefinedBy(Api.COMPILER)
isNameCompatible(String simpleName, Kind kind)689         public boolean isNameCompatible(String simpleName, Kind kind) {
690             try {
691                 return ((JavaFileObject)clientFileObject).isNameCompatible(simpleName, kind);
692             } catch (ClientCodeException e) {
693                 throw e;
694             } catch (RuntimeException | Error e) {
695                 throw new ClientCodeException(e);
696             }
697         }
698 
699         @Override @DefinedBy(Api.COMPILER)
getNestingKind()700         public NestingKind getNestingKind() {
701             try {
702                 return ((JavaFileObject)clientFileObject).getNestingKind();
703             } catch (ClientCodeException e) {
704                 throw e;
705             } catch (RuntimeException | Error e) {
706                 throw new ClientCodeException(e);
707             }
708         }
709 
710         @Override @DefinedBy(Api.COMPILER)
getAccessLevel()711         public Modifier getAccessLevel() {
712             try {
713                 return ((JavaFileObject)clientFileObject).getAccessLevel();
714             } catch (ClientCodeException e) {
715                 throw e;
716             } catch (RuntimeException | Error e) {
717                 throw new ClientCodeException(e);
718             }
719         }
720 
721         @Override
toString()722         public String toString() {
723             return wrappedToString(getClass(), clientFileObject);
724         }
725     }
726 
727     protected class WrappedDiagnosticListener<T /*super JavaFileObject*/> implements DiagnosticListener<T> {
728         protected DiagnosticListener<T> clientDiagnosticListener;
WrappedDiagnosticListener(DiagnosticListener<T> clientDiagnosticListener)729         WrappedDiagnosticListener(DiagnosticListener<T> clientDiagnosticListener) {
730             this.clientDiagnosticListener = Objects.requireNonNull(clientDiagnosticListener);
731         }
732 
733         @Override @DefinedBy(Api.COMPILER)
report(Diagnostic<? extends T> diagnostic)734         public void report(Diagnostic<? extends T> diagnostic) {
735             try {
736                 clientDiagnosticListener.report(unwrap(diagnostic));
737             } catch (ClientCodeException e) {
738                 throw e;
739             } catch (RuntimeException | Error e) {
740                 throw new ClientCodeException(e);
741             }
742         }
743 
744         @Override
toString()745         public String toString() {
746             return wrappedToString(getClass(), clientDiagnosticListener);
747         }
748     }
749 
750     public class DiagnosticSourceUnwrapper implements Diagnostic<JavaFileObject> {
751         public final JCDiagnostic d;
752 
DiagnosticSourceUnwrapper(JCDiagnostic d)753         DiagnosticSourceUnwrapper(JCDiagnostic d) {
754             this.d = d;
755         }
756 
757         @Override @DefinedBy(Api.COMPILER)
getKind()758         public Diagnostic.Kind getKind() {
759             return d.getKind();
760         }
761 
762         @Override @DefinedBy(Api.COMPILER)
getSource()763         public JavaFileObject getSource() {
764             return unwrap(d.getSource());
765         }
766 
767         @Override @DefinedBy(Api.COMPILER)
getPosition()768         public long getPosition() {
769             return d.getPosition();
770         }
771 
772         @Override @DefinedBy(Api.COMPILER)
getStartPosition()773         public long getStartPosition() {
774             return d.getStartPosition();
775         }
776 
777         @Override @DefinedBy(Api.COMPILER)
getEndPosition()778         public long getEndPosition() {
779             return d.getEndPosition();
780         }
781 
782         @Override @DefinedBy(Api.COMPILER)
getLineNumber()783         public long getLineNumber() {
784             return d.getLineNumber();
785         }
786 
787         @Override @DefinedBy(Api.COMPILER)
getColumnNumber()788         public long getColumnNumber() {
789             return d.getColumnNumber();
790         }
791 
792         @Override @DefinedBy(Api.COMPILER)
getCode()793         public String getCode() {
794             return d.getCode();
795         }
796 
797         @Override @DefinedBy(Api.COMPILER)
getMessage(Locale locale)798         public String getMessage(Locale locale) {
799             return d.getMessage(locale);
800         }
801 
802         @Override
toString()803         public String toString() {
804             return d.toString();
805         }
806     }
807 
808     protected class WrappedTaskListener implements TaskListener {
809         protected TaskListener clientTaskListener;
WrappedTaskListener(TaskListener clientTaskListener)810         WrappedTaskListener(TaskListener clientTaskListener) {
811             this.clientTaskListener = Objects.requireNonNull(clientTaskListener);
812         }
813 
814         @Override @DefinedBy(Api.COMPILER_TREE)
started(TaskEvent ev)815         public void started(TaskEvent ev) {
816             try {
817                 clientTaskListener.started(ev);
818             } catch (ClientCodeException e) {
819                 throw e;
820             } catch (RuntimeException | Error e) {
821                 throw new ClientCodeException(e);
822             }
823         }
824 
825         @Override @DefinedBy(Api.COMPILER_TREE)
finished(TaskEvent ev)826         public void finished(TaskEvent ev) {
827             try {
828                 clientTaskListener.finished(ev);
829             } catch (ClientCodeException e) {
830                 throw e;
831             } catch (RuntimeException | Error e) {
832                 throw new ClientCodeException(e);
833             }
834         }
835 
836         @Override
toString()837         public String toString() {
838             return wrappedToString(getClass(), clientTaskListener);
839         }
840     }
841 
842     // </editor-fold>
843 }
844