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