< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java

Print this page




  45 import javax.tools.JavaFileObject;
  46 import javax.tools.JavaFileObject.Kind;
  47 import javax.tools.StandardJavaFileManager;
  48 
  49 import static javax.tools.StandardLocation.*;
  50 
  51 import com.sun.source.util.TaskEvent;
  52 import com.sun.tools.javac.api.MultiTaskListener;
  53 import com.sun.tools.javac.code.*;
  54 import com.sun.tools.javac.code.Scope.WriteableScope;
  55 import com.sun.tools.javac.code.Symbol.*;
  56 import com.sun.tools.javac.code.Type.ClassType;
  57 import com.sun.tools.javac.code.Types;
  58 import com.sun.tools.javac.comp.AttrContext;
  59 import com.sun.tools.javac.comp.Check;
  60 import com.sun.tools.javac.comp.Enter;
  61 import com.sun.tools.javac.comp.Env;
  62 import com.sun.tools.javac.comp.Modules;
  63 import com.sun.tools.javac.file.JavacFileManager;
  64 import com.sun.tools.javac.main.JavaCompiler;

  65 import com.sun.tools.javac.model.JavacElements;
  66 import com.sun.tools.javac.model.JavacTypes;
  67 import com.sun.tools.javac.platform.PlatformDescription;
  68 import com.sun.tools.javac.platform.PlatformDescription.PluginInfo;
  69 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  70 import com.sun.tools.javac.tree.*;
  71 import com.sun.tools.javac.tree.JCTree.*;
  72 import com.sun.tools.javac.util.Abort;
  73 import com.sun.tools.javac.util.Assert;
  74 import com.sun.tools.javac.util.ClientCodeException;
  75 import com.sun.tools.javac.util.Context;
  76 import com.sun.tools.javac.util.Convert;
  77 import com.sun.tools.javac.util.DefinedBy;
  78 import com.sun.tools.javac.util.DefinedBy.Api;
  79 import com.sun.tools.javac.util.Iterators;
  80 import com.sun.tools.javac.util.JCDiagnostic;
  81 import com.sun.tools.javac.util.JavacMessages;
  82 import com.sun.tools.javac.util.List;
  83 import com.sun.tools.javac.util.Log;
  84 import com.sun.tools.javac.util.MatchingUtils;
  85 import com.sun.tools.javac.util.ModuleHelper;
  86 import com.sun.tools.javac.util.Name;
  87 import com.sun.tools.javac.util.Names;
  88 import com.sun.tools.javac.util.Options;
  89 
  90 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
  91 import static com.sun.tools.javac.code.Kinds.Kind.*;
  92 import static com.sun.tools.javac.main.Option.*;
  93 import static com.sun.tools.javac.comp.CompileStates.CompileState;
  94 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
  95 
  96 /**
  97  * Objects of this class hold and manage the state needed to support
  98  * annotation processing.
  99  *
 100  * <p><b>This is NOT part of any supported API.
 101  * If you write code that depends on this, you do so at your own risk.
 102  * This code and its internal interfaces are subject to change or
 103  * deletion without notice.</b>
 104  */
 105 public class JavacProcessingEnvironment implements ProcessingEnvironment, Closeable {
 106     private final Options options;
 107 
 108     private final boolean printProcessorInfo;
 109     private final boolean printRounds;
 110     private final boolean verbose;
 111     private final boolean lint;
 112     private final boolean fatalErrors;


 179     private final Check chk;
 180     private final ModuleSymbol defaultModule;
 181 
 182     private final Context context;
 183 
 184     /** Get the JavacProcessingEnvironment instance for this context. */
 185     public static JavacProcessingEnvironment instance(Context context) {
 186         JavacProcessingEnvironment instance = context.get(JavacProcessingEnvironment.class);
 187         if (instance == null)
 188             instance = new JavacProcessingEnvironment(context);
 189         return instance;
 190     }
 191 
 192     protected JavacProcessingEnvironment(Context context) {
 193         this.context = context;
 194         context.put(JavacProcessingEnvironment.class, this);
 195         log = Log.instance(context);
 196         source = Source.instance(context);
 197         diags = JCDiagnostic.Factory.instance(context);
 198         options = Options.instance(context);
 199         printProcessorInfo = options.isSet(XPRINTPROCESSORINFO);
 200         printRounds = options.isSet(XPRINTROUNDS);
 201         verbose = options.isSet(VERBOSE);
 202         lint = Lint.instance(context).isEnabled(PROCESSING);
 203         compiler = JavaCompiler.instance(context);
 204         if (options.isSet(PROC, "only") || options.isSet(XPRINT)) {
 205             compiler.shouldStopPolicyIfNoError = CompileState.PROCESS;
 206         }
 207         fatalErrors = options.isSet("fatalEnterError");
 208         showResolveErrors = options.isSet("showResolveErrors");
 209         werror = options.isSet(WERROR);
 210         fileManager = context.get(JavaFileManager.class);
 211         platformAnnotations = initPlatformAnnotations();
 212 
 213         // Initialize services before any processors are initialized
 214         // in case processors use them.
 215         filer = new JavacFiler(context);
 216         messager = new JavacMessager(context, this);
 217         elementUtils = JavacElements.instance(context);
 218         typeUtils = JavacTypes.instance(context);
 219         modules = Modules.instance(context);
 220         types = Types.instance(context);
 221         processorOptions = initProcessorOptions();
 222         unmatchedProcessorOptions = initUnmatchedProcessorOptions();
 223         messages = JavacMessages.instance(context);
 224         taskListener = MultiTaskListener.instance(context);
 225         symtab = Symtab.instance(context);
 226         names = Names.instance(context);
 227         enter = Enter.instance(context);
 228         initialCompleter = ClassFinder.instance(context).getCompleter();
 229         chk = Check.instance(context);


 262             } else {
 263                 // If processorpath is not explicitly set, use the classpath.
 264                 processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
 265                     ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH)
 266                     : fileManager.getClassLoader(CLASS_PATH);
 267 
 268                 moduleHelper.addExports(processorClassLoader);
 269 
 270                 if (processorClassLoader != null && processorClassLoader instanceof Closeable) {
 271                     compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
 272                 }
 273             }
 274         } catch (SecurityException e) {
 275             processorLoaderException = e;
 276         }
 277     }
 278 
 279     private void initProcessorIterator(Iterable<? extends Processor> processors) {
 280         Iterator<? extends Processor> processorIterator;
 281 
 282         if (options.isSet(XPRINT)) {
 283             try {
 284                 processorIterator = List.of(new PrintingProcessor()).iterator();
 285             } catch (Throwable t) {
 286                 AssertionError assertError =
 287                     new AssertionError("Problem instantiating PrintingProcessor.");
 288                 assertError.initCause(t);
 289                 throw assertError;
 290             }
 291         } else if (processors != null) {
 292             processorIterator = processors.iterator();
 293         } else {
 294             if (processorLoaderException == null) {
 295                 /*
 296                  * If the "-processor" option is used, search the appropriate
 297                  * path for the named class.  Otherwise, use a service
 298                  * provider mechanism to create the processor iterator.
 299                  */
 300                 String processorNames = options.get(PROCESSOR);
 301                 if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) {
 302                     processorIterator = (processorNames == null) ?
 303                             new ServiceIterator(serviceLoader, log) :
 304                             new NameServiceIterator(serviceLoader, log, processorNames);
 305                 } else if (processorNames != null) {
 306                     processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log);
 307                 } else {
 308                     processorIterator = new ServiceIterator(processorClassLoader, log);
 309                 }
 310             } else {
 311                 /*
 312                  * A security exception will occur if we can't create a classloader.
 313                  * Ignore the exception if, with hindsight, we didn't need it anyway
 314                  * (i.e. no processor was specified either explicitly, or implicitly,
 315                  * in service configuration file.) Otherwise, we cannot continue.
 316                  */
 317                 processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader",
 318                         processorLoaderException);
 319             }
 320         }


 346     }
 347 
 348     /**
 349      * Returns an empty processor iterator if no processors are on the
 350      * relevant path, otherwise if processors are present, logs an
 351      * error.  Called when a service loader is unavailable for some
 352      * reason, either because a service loader class cannot be found
 353      * or because a security policy prevents class loaders from being
 354      * created.
 355      *
 356      * @param key The resource key to use to log an error message
 357      * @param e   If non-null, pass this exception to Abort
 358      */
 359     private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) {
 360         if (fileManager instanceof JavacFileManager) {
 361             StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager;
 362             Iterable<? extends Path> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
 363                 ? standardFileManager.getLocationAsPaths(ANNOTATION_PROCESSOR_PATH)
 364                 : standardFileManager.getLocationAsPaths(CLASS_PATH);
 365 
 366             if (needClassLoader(options.get(PROCESSOR), workingPath) )
 367                 handleException(key, e);
 368 
 369         } else {
 370             handleException(key, e);
 371         }
 372 
 373         java.util.List<Processor> pl = Collections.emptyList();
 374         return pl.iterator();
 375     }
 376 
 377     /**
 378      * Handle a security exception thrown during initializing the
 379      * Processor iterator.
 380      */
 381     private void handleException(String key, Exception e) {
 382         if (e != null) {
 383             log.error(key, e.getLocalizedMessage());
 384             throw new Abort(e);
 385         } else {
 386             log.error(key);




  45 import javax.tools.JavaFileObject;
  46 import javax.tools.JavaFileObject.Kind;
  47 import javax.tools.StandardJavaFileManager;
  48 
  49 import static javax.tools.StandardLocation.*;
  50 
  51 import com.sun.source.util.TaskEvent;
  52 import com.sun.tools.javac.api.MultiTaskListener;
  53 import com.sun.tools.javac.code.*;
  54 import com.sun.tools.javac.code.Scope.WriteableScope;
  55 import com.sun.tools.javac.code.Symbol.*;
  56 import com.sun.tools.javac.code.Type.ClassType;
  57 import com.sun.tools.javac.code.Types;
  58 import com.sun.tools.javac.comp.AttrContext;
  59 import com.sun.tools.javac.comp.Check;
  60 import com.sun.tools.javac.comp.Enter;
  61 import com.sun.tools.javac.comp.Env;
  62 import com.sun.tools.javac.comp.Modules;
  63 import com.sun.tools.javac.file.JavacFileManager;
  64 import com.sun.tools.javac.main.JavaCompiler;
  65 import com.sun.tools.javac.main.Option;
  66 import com.sun.tools.javac.model.JavacElements;
  67 import com.sun.tools.javac.model.JavacTypes;
  68 import com.sun.tools.javac.platform.PlatformDescription;
  69 import com.sun.tools.javac.platform.PlatformDescription.PluginInfo;
  70 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  71 import com.sun.tools.javac.tree.*;
  72 import com.sun.tools.javac.tree.JCTree.*;
  73 import com.sun.tools.javac.util.Abort;
  74 import com.sun.tools.javac.util.Assert;
  75 import com.sun.tools.javac.util.ClientCodeException;
  76 import com.sun.tools.javac.util.Context;
  77 import com.sun.tools.javac.util.Convert;
  78 import com.sun.tools.javac.util.DefinedBy;
  79 import com.sun.tools.javac.util.DefinedBy.Api;
  80 import com.sun.tools.javac.util.Iterators;
  81 import com.sun.tools.javac.util.JCDiagnostic;
  82 import com.sun.tools.javac.util.JavacMessages;
  83 import com.sun.tools.javac.util.List;
  84 import com.sun.tools.javac.util.Log;
  85 import com.sun.tools.javac.util.MatchingUtils;
  86 import com.sun.tools.javac.util.ModuleHelper;
  87 import com.sun.tools.javac.util.Name;
  88 import com.sun.tools.javac.util.Names;
  89 import com.sun.tools.javac.util.Options;
  90 
  91 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
  92 import static com.sun.tools.javac.code.Kinds.Kind.*;

  93 import static com.sun.tools.javac.comp.CompileStates.CompileState;
  94 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
  95 
  96 /**
  97  * Objects of this class hold and manage the state needed to support
  98  * annotation processing.
  99  *
 100  * <p><b>This is NOT part of any supported API.
 101  * If you write code that depends on this, you do so at your own risk.
 102  * This code and its internal interfaces are subject to change or
 103  * deletion without notice.</b>
 104  */
 105 public class JavacProcessingEnvironment implements ProcessingEnvironment, Closeable {
 106     private final Options options;
 107 
 108     private final boolean printProcessorInfo;
 109     private final boolean printRounds;
 110     private final boolean verbose;
 111     private final boolean lint;
 112     private final boolean fatalErrors;


 179     private final Check chk;
 180     private final ModuleSymbol defaultModule;
 181 
 182     private final Context context;
 183 
 184     /** Get the JavacProcessingEnvironment instance for this context. */
 185     public static JavacProcessingEnvironment instance(Context context) {
 186         JavacProcessingEnvironment instance = context.get(JavacProcessingEnvironment.class);
 187         if (instance == null)
 188             instance = new JavacProcessingEnvironment(context);
 189         return instance;
 190     }
 191 
 192     protected JavacProcessingEnvironment(Context context) {
 193         this.context = context;
 194         context.put(JavacProcessingEnvironment.class, this);
 195         log = Log.instance(context);
 196         source = Source.instance(context);
 197         diags = JCDiagnostic.Factory.instance(context);
 198         options = Options.instance(context);
 199         printProcessorInfo = options.isSet(Option.XPRINTPROCESSORINFO);
 200         printRounds = options.isSet(Option.XPRINTROUNDS);
 201         verbose = options.isSet(Option.VERBOSE);
 202         lint = Lint.instance(context).isEnabled(PROCESSING);
 203         compiler = JavaCompiler.instance(context);
 204         if (options.isSet(Option.PROC, "only") || options.isSet(Option.XPRINT)) {
 205             compiler.shouldStopPolicyIfNoError = CompileState.PROCESS;
 206         }
 207         fatalErrors = options.isSet("fatalEnterError");
 208         showResolveErrors = options.isSet("showResolveErrors");
 209         werror = options.isSet(Option.WERROR);
 210         fileManager = context.get(JavaFileManager.class);
 211         platformAnnotations = initPlatformAnnotations();
 212 
 213         // Initialize services before any processors are initialized
 214         // in case processors use them.
 215         filer = new JavacFiler(context);
 216         messager = new JavacMessager(context, this);
 217         elementUtils = JavacElements.instance(context);
 218         typeUtils = JavacTypes.instance(context);
 219         modules = Modules.instance(context);
 220         types = Types.instance(context);
 221         processorOptions = initProcessorOptions();
 222         unmatchedProcessorOptions = initUnmatchedProcessorOptions();
 223         messages = JavacMessages.instance(context);
 224         taskListener = MultiTaskListener.instance(context);
 225         symtab = Symtab.instance(context);
 226         names = Names.instance(context);
 227         enter = Enter.instance(context);
 228         initialCompleter = ClassFinder.instance(context).getCompleter();
 229         chk = Check.instance(context);


 262             } else {
 263                 // If processorpath is not explicitly set, use the classpath.
 264                 processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
 265                     ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH)
 266                     : fileManager.getClassLoader(CLASS_PATH);
 267 
 268                 moduleHelper.addExports(processorClassLoader);
 269 
 270                 if (processorClassLoader != null && processorClassLoader instanceof Closeable) {
 271                     compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
 272                 }
 273             }
 274         } catch (SecurityException e) {
 275             processorLoaderException = e;
 276         }
 277     }
 278 
 279     private void initProcessorIterator(Iterable<? extends Processor> processors) {
 280         Iterator<? extends Processor> processorIterator;
 281 
 282         if (options.isSet(Option.XPRINT)) {
 283             try {
 284                 processorIterator = List.of(new PrintingProcessor()).iterator();
 285             } catch (Throwable t) {
 286                 AssertionError assertError =
 287                     new AssertionError("Problem instantiating PrintingProcessor.");
 288                 assertError.initCause(t);
 289                 throw assertError;
 290             }
 291         } else if (processors != null) {
 292             processorIterator = processors.iterator();
 293         } else {
 294             if (processorLoaderException == null) {
 295                 /*
 296                  * If the "-processor" option is used, search the appropriate
 297                  * path for the named class.  Otherwise, use a service
 298                  * provider mechanism to create the processor iterator.
 299                  */
 300                 String processorNames = options.get(Option.PROCESSOR);
 301                 if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) {
 302                     processorIterator = (processorNames == null) ?
 303                             new ServiceIterator(serviceLoader, log) :
 304                             new NameServiceIterator(serviceLoader, log, processorNames);
 305                 } else if (processorNames != null) {
 306                     processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log);
 307                 } else {
 308                     processorIterator = new ServiceIterator(processorClassLoader, log);
 309                 }
 310             } else {
 311                 /*
 312                  * A security exception will occur if we can't create a classloader.
 313                  * Ignore the exception if, with hindsight, we didn't need it anyway
 314                  * (i.e. no processor was specified either explicitly, or implicitly,
 315                  * in service configuration file.) Otherwise, we cannot continue.
 316                  */
 317                 processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader",
 318                         processorLoaderException);
 319             }
 320         }


 346     }
 347 
 348     /**
 349      * Returns an empty processor iterator if no processors are on the
 350      * relevant path, otherwise if processors are present, logs an
 351      * error.  Called when a service loader is unavailable for some
 352      * reason, either because a service loader class cannot be found
 353      * or because a security policy prevents class loaders from being
 354      * created.
 355      *
 356      * @param key The resource key to use to log an error message
 357      * @param e   If non-null, pass this exception to Abort
 358      */
 359     private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) {
 360         if (fileManager instanceof JavacFileManager) {
 361             StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager;
 362             Iterable<? extends Path> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
 363                 ? standardFileManager.getLocationAsPaths(ANNOTATION_PROCESSOR_PATH)
 364                 : standardFileManager.getLocationAsPaths(CLASS_PATH);
 365 
 366             if (needClassLoader(options.get(Option.PROCESSOR), workingPath) )
 367                 handleException(key, e);
 368 
 369         } else {
 370             handleException(key, e);
 371         }
 372 
 373         java.util.List<Processor> pl = Collections.emptyList();
 374         return pl.iterator();
 375     }
 376 
 377     /**
 378      * Handle a security exception thrown during initializing the
 379      * Processor iterator.
 380      */
 381     private void handleException(String key, Exception e) {
 382         if (e != null) {
 383             log.error(key, e.getLocalizedMessage());
 384             throw new Abort(e);
 385         } else {
 386             log.error(key);


< prev index next >