src/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java

Tue, 29 Mar 2011 16:41:18 +0100

author
mcimadamore
date
Tue, 29 Mar 2011 16:41:18 +0100
changeset 951
de1c65ecfec2
parent 946
31e5cfc5a990
child 1073
f85d980faaf8
permissions
-rw-r--r--

7027157: Project Coin: javac warnings for AutoCloseable.close throwing InterruptedException
Summary: javac should warn about use/declaration of AutoCloseable subclasses that can throw InterruptedException
Reviewed-by: jjg

     1 /*
     2  * Copyright (c) 2011, 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  */
    27 package com.sun.tools.javac.api;
    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.net.URI;
    35 import java.util.ArrayList;
    36 import java.util.Collections;
    37 import java.util.HashMap;
    38 import java.util.Iterator;
    39 import java.util.List;
    40 import java.util.Map;
    41 import java.util.Set;
    43 import javax.lang.model.element.NestingKind;
    44 import javax.tools.Diagnostic;
    45 import javax.tools.FileObject;
    46 import javax.tools.JavaFileManager;
    47 import javax.tools.JavaFileManager.Location;
    48 import javax.tools.JavaFileObject;
    50 import com.sun.source.util.TaskEvent;
    51 import com.sun.source.util.TaskListener;
    52 import com.sun.tools.javac.util.ClientCodeException;
    53 import com.sun.tools.javac.util.Context;
    54 import java.lang.annotation.ElementType;
    55 import java.lang.annotation.Retention;
    56 import java.lang.annotation.RetentionPolicy;
    57 import java.lang.annotation.Target;
    58 import javax.lang.model.element.Modifier;
    59 import javax.tools.DiagnosticListener;
    60 import javax.tools.JavaFileObject.Kind;
    62 /**
    63  *  Wrap objects to enable unchecked exceptions to be caught and handled.
    64  *
    65  *  For each method, exceptions are handled as follows:
    66  *  <ul>
    67  *  <li>Checked exceptions are left alone and propogate upwards in the
    68  *      obvious way, since they are an expected aspect of the method's
    69  *      specification.
    70  *  <li>Unchecked exceptions which have already been caught and wrapped in
    71  *      ClientCodeException are left alone to continue propogating upwards.
    72  *  <li>All other unchecked exceptions (i.e. subtypes of RuntimeException
    73  *      and Error) and caught, and rethrown as a ClientCodeException with
    74  *      its cause set to the original exception.
    75  *  </ul>
    76  *
    77  *  The intent is that ClientCodeException can be caught at an appropriate point
    78  *  in the program and can be distinguished from any unanticipated unchecked
    79  *  exceptions arising in the main body of the code (i.e. bugs.) When the
    80  *  ClientCodeException has been caught, either a suitable message can be
    81  *  generated, or if appropriate, the original cause can be rethrown.
    82  *
    83  *  <p><b>This is NOT part of any supported API.
    84  *  If you write code that depends on this, you do so at your own risk.
    85  *  This code and its internal interfaces are subject to change or
    86  *  deletion without notice.</b>
    87  */
    88 public class ClientCodeWrapper {
    89     @Retention(RetentionPolicy.RUNTIME)
    90     @Target(ElementType.TYPE)
    91     public @interface Trusted { }
    93     public static ClientCodeWrapper instance(Context context) {
    94         ClientCodeWrapper instance = context.get(ClientCodeWrapper.class);
    95         if (instance == null)
    96             instance = new ClientCodeWrapper(context);
    97         return instance;
    98     }
   100     /**
   101      * A map to cache the results of whether or not a specific classes can
   102      * be "trusted", and thus does not need to be wrapped.
   103      */
   104     Map<Class<?>, Boolean> trustedClasses;
   106     protected ClientCodeWrapper(Context context) {
   107         trustedClasses = new HashMap<Class<?>, Boolean>();
   108     }
   110     public JavaFileManager wrap(JavaFileManager fm) {
   111         if (isTrusted(fm))
   112             return fm;
   113         return new WrappedJavaFileManager(fm);
   114     }
   116     public FileObject wrap(FileObject fo) {
   117         if (isTrusted(fo))
   118             return fo;
   119         return new WrappedFileObject(fo);
   120     }
   122     FileObject unwrap(FileObject fo) {
   123         if (fo instanceof WrappedFileObject)
   124             return ((WrappedFileObject) fo).clientFileObject;
   125         else
   126             return fo;
   127     }
   129     public JavaFileObject wrap(JavaFileObject fo) {
   130         if (isTrusted(fo))
   131             return fo;
   132         return new WrappedJavaFileObject(fo);
   133     }
   135     public Iterable<JavaFileObject> wrapJavaFileObjects(Iterable<? extends JavaFileObject> list) {
   136         List<JavaFileObject> wrapped = new ArrayList<JavaFileObject>();
   137         for (JavaFileObject fo : list)
   138             wrapped.add(wrap(fo));
   139         return Collections.unmodifiableList(wrapped);
   140     }
   142     JavaFileObject unwrap(JavaFileObject fo) {
   143         if (fo instanceof WrappedJavaFileObject)
   144             return ((JavaFileObject) ((WrappedJavaFileObject) fo).clientFileObject);
   145         else
   146             return fo;
   147     }
   149     <T> DiagnosticListener<T> wrap(DiagnosticListener<T> dl) {
   150         if (isTrusted(dl))
   151             return dl;
   152         return new WrappedDiagnosticListener<T>(dl);
   153     }
   155     TaskListener wrap(TaskListener tl) {
   156         if (isTrusted(tl))
   157             return tl;
   158         return new WrappedTaskListener(tl);
   159     }
   161     protected boolean isTrusted(Object o) {
   162         Class<?> c = o.getClass();
   163         Boolean trusted = trustedClasses.get(c);
   164         if (trusted == null) {
   165             trusted = c.getName().startsWith("com.sun.tools.javac.")
   166                     || c.isAnnotationPresent(Trusted.class);
   167             trustedClasses.put(c, trusted);
   168         }
   169         return trusted;
   170     }
   172     // <editor-fold defaultstate="collapsed" desc="Wrapper classes">
   174     // FIXME: all these classes should be converted to use multi-catch when
   175     // that is available in the bootstrap compiler.
   177     protected class WrappedJavaFileManager implements JavaFileManager {
   178         protected JavaFileManager clientJavaFileManager;
   179         WrappedJavaFileManager(JavaFileManager clientJavaFileManager) {
   180             clientJavaFileManager.getClass(); // null check
   181             this.clientJavaFileManager = clientJavaFileManager;
   182         }
   184         @Override
   185         public ClassLoader getClassLoader(Location location) {
   186             try {
   187                 return clientJavaFileManager.getClassLoader(location);
   188             } catch (ClientCodeException e) {
   189                 throw e;
   190             } catch (RuntimeException e) {
   191                 throw new ClientCodeException(e);
   192             } catch (Error e) {
   193                 throw new ClientCodeException(e);
   194             }
   195         }
   197         @Override
   198         public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
   199             try {
   200                 return wrapJavaFileObjects(clientJavaFileManager.list(location, packageName, kinds, recurse));
   201             } catch (ClientCodeException e) {
   202                 throw e;
   203             } catch (RuntimeException e) {
   204                 throw new ClientCodeException(e);
   205             } catch (Error e) {
   206                 throw new ClientCodeException(e);
   207             }
   208         }
   210         @Override
   211         public String inferBinaryName(Location location, JavaFileObject file) {
   212             try {
   213                 return clientJavaFileManager.inferBinaryName(location, unwrap(file));
   214             } catch (ClientCodeException e) {
   215                 throw e;
   216             } catch (RuntimeException e) {
   217                 throw new ClientCodeException(e);
   218             } catch (Error e) {
   219                 throw new ClientCodeException(e);
   220             }
   221         }
   223         @Override
   224         public boolean isSameFile(FileObject a, FileObject b) {
   225             try {
   226                 return clientJavaFileManager.isSameFile(unwrap(a), unwrap(b));
   227             } catch (ClientCodeException e) {
   228                 throw e;
   229             } catch (RuntimeException e) {
   230                 throw new ClientCodeException(e);
   231             } catch (Error e) {
   232                 throw new ClientCodeException(e);
   233             }
   234         }
   236         @Override
   237         public boolean handleOption(String current, Iterator<String> remaining) {
   238             try {
   239                 return clientJavaFileManager.handleOption(current, remaining);
   240             } catch (ClientCodeException e) {
   241                 throw e;
   242             } catch (RuntimeException e) {
   243                 throw new ClientCodeException(e);
   244             } catch (Error e) {
   245                 throw new ClientCodeException(e);
   246             }
   247         }
   249         @Override
   250         public boolean hasLocation(Location location) {
   251             try {
   252                 return clientJavaFileManager.hasLocation(location);
   253             } catch (ClientCodeException e) {
   254                 throw e;
   255             } catch (RuntimeException e) {
   256                 throw new ClientCodeException(e);
   257             } catch (Error e) {
   258                 throw new ClientCodeException(e);
   259             }
   260         }
   262         @Override
   263         public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
   264             try {
   265                 return wrap(clientJavaFileManager.getJavaFileForInput(location, className, kind));
   266             } catch (ClientCodeException e) {
   267                 throw e;
   268             } catch (RuntimeException e) {
   269                 throw new ClientCodeException(e);
   270             } catch (Error e) {
   271                 throw new ClientCodeException(e);
   272             }
   273         }
   275         @Override
   276         public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
   277             try {
   278                 return wrap(clientJavaFileManager.getJavaFileForOutput(location, className, kind, unwrap(sibling)));
   279             } catch (ClientCodeException e) {
   280                 throw e;
   281             } catch (RuntimeException e) {
   282                 throw new ClientCodeException(e);
   283             } catch (Error e) {
   284                 throw new ClientCodeException(e);
   285             }
   286         }
   288         @Override
   289         public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
   290             try {
   291                 return wrap(clientJavaFileManager.getFileForInput(location, packageName, relativeName));
   292             } catch (ClientCodeException e) {
   293                 throw e;
   294             } catch (RuntimeException e) {
   295                 throw new ClientCodeException(e);
   296             } catch (Error e) {
   297                 throw new ClientCodeException(e);
   298             }
   299         }
   301         @Override
   302         public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException {
   303             try {
   304                 return wrap(clientJavaFileManager.getFileForOutput(location, packageName, relativeName, unwrap(sibling)));
   305             } catch (ClientCodeException e) {
   306                 throw e;
   307             } catch (RuntimeException e) {
   308                 throw new ClientCodeException(e);
   309             } catch (Error e) {
   310                 throw new ClientCodeException(e);
   311             }
   312         }
   314         @Override
   315         public void flush() throws IOException {
   316             try {
   317                 clientJavaFileManager.flush();
   318             } catch (ClientCodeException e) {
   319                 throw e;
   320             } catch (RuntimeException e) {
   321                 throw new ClientCodeException(e);
   322             } catch (Error e) {
   323                 throw new ClientCodeException(e);
   324             }
   325         }
   327         @Override
   328         public void close() throws IOException {
   329             try {
   330                 clientJavaFileManager.close();
   331             } catch (ClientCodeException e) {
   332                 throw e;
   333             } catch (RuntimeException e) {
   334                 throw new ClientCodeException(e);
   335             } catch (Error e) {
   336                 throw new ClientCodeException(e);
   337             }
   338         }
   340         @Override
   341         public int isSupportedOption(String option) {
   342             try {
   343                 return clientJavaFileManager.isSupportedOption(option);
   344             } catch (ClientCodeException e) {
   345                 throw e;
   346             } catch (RuntimeException e) {
   347                 throw new ClientCodeException(e);
   348             } catch (Error e) {
   349                 throw new ClientCodeException(e);
   350             }
   351         }
   352     }
   354     protected class WrappedFileObject implements FileObject {
   355         protected FileObject clientFileObject;
   356         WrappedFileObject(FileObject clientFileObject) {
   357             clientFileObject.getClass(); // null check
   358             this.clientFileObject = clientFileObject;
   359         }
   361         @Override
   362         public URI toUri() {
   363             try {
   364                 return clientFileObject.toUri();
   365             } catch (ClientCodeException e) {
   366                 throw e;
   367             } catch (RuntimeException e) {
   368                 throw new ClientCodeException(e);
   369             } catch (Error e) {
   370                 throw new ClientCodeException(e);
   371             }
   372         }
   374         @Override
   375         public String getName() {
   376             try {
   377                 return clientFileObject.getName();
   378             } catch (ClientCodeException e) {
   379                 throw e;
   380             } catch (RuntimeException e) {
   381                 throw new ClientCodeException(e);
   382             } catch (Error e) {
   383                 throw new ClientCodeException(e);
   384             }
   385         }
   387         @Override
   388         public InputStream openInputStream() throws IOException {
   389             try {
   390                 return clientFileObject.openInputStream();
   391             } catch (ClientCodeException e) {
   392                 throw e;
   393             } catch (RuntimeException e) {
   394                 throw new ClientCodeException(e);
   395             } catch (Error e) {
   396                 throw new ClientCodeException(e);
   397             }
   398         }
   400         @Override
   401         public OutputStream openOutputStream() throws IOException {
   402             try {
   403                 return clientFileObject.openOutputStream();
   404             } catch (ClientCodeException e) {
   405                 throw e;
   406             } catch (RuntimeException e) {
   407                 throw new ClientCodeException(e);
   408             } catch (Error e) {
   409                 throw new ClientCodeException(e);
   410             }
   411         }
   413         @Override
   414         public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
   415             try {
   416                 return clientFileObject.openReader(ignoreEncodingErrors);
   417             } catch (ClientCodeException e) {
   418                 throw e;
   419             } catch (RuntimeException e) {
   420                 throw new ClientCodeException(e);
   421             } catch (Error e) {
   422                 throw new ClientCodeException(e);
   423             }
   424         }
   426         @Override
   427         public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
   428             try {
   429                 return clientFileObject.getCharContent(ignoreEncodingErrors);
   430             } catch (ClientCodeException e) {
   431                 throw e;
   432             } catch (RuntimeException e) {
   433                 throw new ClientCodeException(e);
   434             } catch (Error e) {
   435                 throw new ClientCodeException(e);
   436             }
   437         }
   439         @Override
   440         public Writer openWriter() throws IOException {
   441             try {
   442                 return clientFileObject.openWriter();
   443             } catch (ClientCodeException e) {
   444                 throw e;
   445             } catch (RuntimeException e) {
   446                 throw new ClientCodeException(e);
   447             } catch (Error e) {
   448                 throw new ClientCodeException(e);
   449             }
   450         }
   452         @Override
   453         public long getLastModified() {
   454             try {
   455                 return clientFileObject.getLastModified();
   456             } catch (ClientCodeException e) {
   457                 throw e;
   458             } catch (RuntimeException e) {
   459                 throw new ClientCodeException(e);
   460             } catch (Error e) {
   461                 throw new ClientCodeException(e);
   462             }
   463         }
   465         @Override
   466         public boolean delete() {
   467             try {
   468                 return clientFileObject.delete();
   469             } catch (ClientCodeException e) {
   470                 throw e;
   471             } catch (RuntimeException e) {
   472                 throw new ClientCodeException(e);
   473             } catch (Error e) {
   474                 throw new ClientCodeException(e);
   475             }
   476         }
   477     }
   479     protected class WrappedJavaFileObject extends WrappedFileObject implements JavaFileObject {
   480         WrappedJavaFileObject(JavaFileObject clientJavaFileObject) {
   481             super(clientJavaFileObject);
   482         }
   484         @Override
   485         public Kind getKind() {
   486             try {
   487                 return ((JavaFileObject)clientFileObject).getKind();
   488             } catch (ClientCodeException e) {
   489                 throw e;
   490             } catch (RuntimeException e) {
   491                 throw new ClientCodeException(e);
   492             } catch (Error e) {
   493                 throw new ClientCodeException(e);
   494             }
   495         }
   497         @Override
   498         public boolean isNameCompatible(String simpleName, Kind kind) {
   499             try {
   500                 return ((JavaFileObject)clientFileObject).isNameCompatible(simpleName, kind);
   501             } catch (ClientCodeException e) {
   502                 throw e;
   503             } catch (RuntimeException e) {
   504                 throw new ClientCodeException(e);
   505             } catch (Error e) {
   506                 throw new ClientCodeException(e);
   507             }
   508         }
   510         @Override
   511         public NestingKind getNestingKind() {
   512             try {
   513                 return ((JavaFileObject)clientFileObject).getNestingKind();
   514             } catch (ClientCodeException e) {
   515                 throw e;
   516             } catch (RuntimeException e) {
   517                 throw new ClientCodeException(e);
   518             } catch (Error e) {
   519                 throw new ClientCodeException(e);
   520             }
   521         }
   523         @Override
   524         public Modifier getAccessLevel() {
   525             try {
   526                 return ((JavaFileObject)clientFileObject).getAccessLevel();
   527             } catch (ClientCodeException e) {
   528                 throw e;
   529             } catch (RuntimeException e) {
   530                 throw new ClientCodeException(e);
   531             } catch (Error e) {
   532                 throw new ClientCodeException(e);
   533             }
   534         }
   535     }
   537     protected class WrappedDiagnosticListener<T> implements DiagnosticListener<T> {
   538         protected DiagnosticListener<T> clientDiagnosticListener;
   539         WrappedDiagnosticListener(DiagnosticListener<T> clientDiagnosticListener) {
   540             clientDiagnosticListener.getClass(); // null check
   541             this.clientDiagnosticListener = clientDiagnosticListener;
   542         }
   544         @Override
   545         public void report(Diagnostic<? extends T> diagnostic) {
   546             try {
   547                 clientDiagnosticListener.report(diagnostic);
   548             } catch (ClientCodeException e) {
   549                 throw e;
   550             } catch (RuntimeException e) {
   551                 throw new ClientCodeException(e);
   552             } catch (Error e) {
   553                 throw new ClientCodeException(e);
   554             }
   555         }
   556     }
   558     protected class WrappedTaskListener implements TaskListener {
   559         protected TaskListener clientTaskListener;
   560         WrappedTaskListener(TaskListener clientTaskListener) {
   561             clientTaskListener.getClass(); // null check
   562             this.clientTaskListener = clientTaskListener;
   563         }
   565         @Override
   566         public void started(TaskEvent ev) {
   567             try {
   568                 clientTaskListener.started(ev);
   569             } catch (ClientCodeException e) {
   570                 throw e;
   571             } catch (RuntimeException e) {
   572                 throw new ClientCodeException(e);
   573             } catch (Error e) {
   574                 throw new ClientCodeException(e);
   575             }
   576         }
   578         @Override
   579         public void finished(TaskEvent ev) {
   580             try {
   581                 clientTaskListener.finished(ev);
   582             } catch (ClientCodeException e) {
   583                 throw e;
   584             } catch (RuntimeException e) {
   585                 throw new ClientCodeException(e);
   586             } catch (Error e) {
   587                 throw new ClientCodeException(e);
   588             }
   589         }
   590     }
   592     // </editor-fold>
   593 }

mercurial