langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
changeset 36526 3b41f1c69604
parent 36492 12abe038f3d9
child 37759 f0b5daef41b6
equal deleted inserted replaced
36525:4caf88912b7f 36526:3b41f1c69604
    25 
    25 
    26 package com.sun.tools.javac.processing;
    26 package com.sun.tools.javac.processing;
    27 
    27 
    28 import java.io.Closeable;
    28 import java.io.Closeable;
    29 import java.io.File;
    29 import java.io.File;
       
    30 import java.io.IOException;
    30 import java.io.PrintWriter;
    31 import java.io.PrintWriter;
    31 import java.io.StringWriter;
    32 import java.io.StringWriter;
       
    33 import java.lang.reflect.Method;
    32 import java.net.MalformedURLException;
    34 import java.net.MalformedURLException;
    33 import java.net.URL;
    35 import java.net.URL;
    34 import java.nio.file.Path;
    36 import java.nio.file.Path;
    35 import java.util.*;
    37 import java.util.*;
    36 import java.util.regex.*;
    38 import java.util.regex.*;
    40 import javax.lang.model.SourceVersion;
    42 import javax.lang.model.SourceVersion;
    41 import javax.lang.model.element.*;
    43 import javax.lang.model.element.*;
    42 import javax.lang.model.util.*;
    44 import javax.lang.model.util.*;
    43 import javax.tools.JavaFileManager;
    45 import javax.tools.JavaFileManager;
    44 import javax.tools.JavaFileObject;
    46 import javax.tools.JavaFileObject;
       
    47 import javax.tools.JavaFileObject.Kind;
    45 import javax.tools.StandardJavaFileManager;
    48 import javax.tools.StandardJavaFileManager;
    46 
    49 
    47 import static javax.tools.StandardLocation.*;
    50 import static javax.tools.StandardLocation.*;
    48 
    51 
    49 import com.sun.source.util.TaskEvent;
    52 import com.sun.source.util.TaskEvent;
    50 import com.sun.tools.javac.api.MultiTaskListener;
    53 import com.sun.tools.javac.api.MultiTaskListener;
    51 import com.sun.tools.javac.code.*;
    54 import com.sun.tools.javac.code.*;
       
    55 import com.sun.tools.javac.code.Scope.WriteableScope;
    52 import com.sun.tools.javac.code.Symbol.*;
    56 import com.sun.tools.javac.code.Symbol.*;
    53 import com.sun.tools.javac.code.Type.ClassType;
    57 import com.sun.tools.javac.code.Type.ClassType;
    54 import com.sun.tools.javac.code.Types;
    58 import com.sun.tools.javac.code.Types;
    55 import com.sun.tools.javac.comp.AttrContext;
    59 import com.sun.tools.javac.comp.AttrContext;
    56 import com.sun.tools.javac.comp.Check;
    60 import com.sun.tools.javac.comp.Check;
    57 import com.sun.tools.javac.comp.Enter;
    61 import com.sun.tools.javac.comp.Enter;
    58 import com.sun.tools.javac.comp.Env;
    62 import com.sun.tools.javac.comp.Env;
       
    63 import com.sun.tools.javac.comp.Modules;
    59 import com.sun.tools.javac.file.JavacFileManager;
    64 import com.sun.tools.javac.file.JavacFileManager;
    60 import com.sun.tools.javac.main.JavaCompiler;
    65 import com.sun.tools.javac.main.JavaCompiler;
    61 import com.sun.tools.javac.model.JavacElements;
    66 import com.sun.tools.javac.model.JavacElements;
    62 import com.sun.tools.javac.model.JavacTypes;
    67 import com.sun.tools.javac.model.JavacTypes;
    63 import com.sun.tools.javac.platform.PlatformDescription;
    68 import com.sun.tools.javac.platform.PlatformDescription;
    64 import com.sun.tools.javac.platform.PlatformDescription.PluginInfo;
    69 import com.sun.tools.javac.platform.PlatformDescription.PluginInfo;
       
    70 import com.sun.tools.javac.resources.CompilerProperties.Errors;
    65 import com.sun.tools.javac.tree.*;
    71 import com.sun.tools.javac.tree.*;
    66 import com.sun.tools.javac.tree.JCTree.*;
    72 import com.sun.tools.javac.tree.JCTree.*;
    67 import com.sun.tools.javac.util.Abort;
    73 import com.sun.tools.javac.util.Abort;
    68 import com.sun.tools.javac.util.Assert;
    74 import com.sun.tools.javac.util.Assert;
    69 import com.sun.tools.javac.util.ClientCodeException;
    75 import com.sun.tools.javac.util.ClientCodeException;
    75 import com.sun.tools.javac.util.JCDiagnostic;
    81 import com.sun.tools.javac.util.JCDiagnostic;
    76 import com.sun.tools.javac.util.JavacMessages;
    82 import com.sun.tools.javac.util.JavacMessages;
    77 import com.sun.tools.javac.util.List;
    83 import com.sun.tools.javac.util.List;
    78 import com.sun.tools.javac.util.Log;
    84 import com.sun.tools.javac.util.Log;
    79 import com.sun.tools.javac.util.MatchingUtils;
    85 import com.sun.tools.javac.util.MatchingUtils;
       
    86 import com.sun.tools.javac.util.ModuleHelper;
    80 import com.sun.tools.javac.util.Name;
    87 import com.sun.tools.javac.util.Name;
    81 import com.sun.tools.javac.util.Names;
    88 import com.sun.tools.javac.util.Names;
    82 import com.sun.tools.javac.util.Options;
    89 import com.sun.tools.javac.util.Options;
    83 import com.sun.tools.javac.util.ServiceLoader;
       
    84 
    90 
    85 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
    91 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
    86 import static com.sun.tools.javac.code.Kinds.Kind.*;
    92 import static com.sun.tools.javac.code.Kinds.Kind.*;
    87 import static com.sun.tools.javac.main.Option.*;
    93 import static com.sun.tools.javac.main.Option.*;
    88 import static com.sun.tools.javac.comp.CompileStates.CompileState;
    94 import static com.sun.tools.javac.comp.CompileStates.CompileState;
   110 
   116 
   111     private final JavacFiler filer;
   117     private final JavacFiler filer;
   112     private final JavacMessager messager;
   118     private final JavacMessager messager;
   113     private final JavacElements elementUtils;
   119     private final JavacElements elementUtils;
   114     private final JavacTypes typeUtils;
   120     private final JavacTypes typeUtils;
       
   121     private final JavaCompiler compiler;
       
   122     private final Modules modules;
       
   123     private final ModuleHelper moduleHelper;
   115     private final Types types;
   124     private final Types types;
   116     private final JavaCompiler compiler;
       
   117 
   125 
   118     /**
   126     /**
   119      * Holds relevant state history of which processors have been
   127      * Holds relevant state history of which processors have been
   120      * used.
   128      * used.
   121      */
   129      */
   152      * Source level of the compile.
   160      * Source level of the compile.
   153      */
   161      */
   154     Source source;
   162     Source source;
   155 
   163 
   156     private ClassLoader processorClassLoader;
   164     private ClassLoader processorClassLoader;
   157     private SecurityException processorClassLoaderException;
   165     private ServiceLoader<Processor> serviceLoader;
       
   166     private SecurityException processorLoaderException;
       
   167 
       
   168     private final JavaFileManager fileManager;
   158 
   169 
   159     /**
   170     /**
   160      * JavacMessages object used for localization
   171      * JavacMessages object used for localization
   161      */
   172      */
   162     private JavacMessages messages;
   173     private JavacMessages messages;
   165     private final Symtab symtab;
   176     private final Symtab symtab;
   166     private final Names names;
   177     private final Names names;
   167     private final Enter enter;
   178     private final Enter enter;
   168     private final Completer initialCompleter;
   179     private final Completer initialCompleter;
   169     private final Check chk;
   180     private final Check chk;
       
   181     private final ModuleSymbol defaultModule;
   170 
   182 
   171     private final Context context;
   183     private final Context context;
   172 
   184 
   173     /** Get the JavacProcessingEnvironment instance for this context. */
   185     /** Get the JavacProcessingEnvironment instance for this context. */
   174     public static JavacProcessingEnvironment instance(Context context) {
   186     public static JavacProcessingEnvironment instance(Context context) {
   194             compiler.shouldStopPolicyIfNoError = CompileState.PROCESS;
   206             compiler.shouldStopPolicyIfNoError = CompileState.PROCESS;
   195         }
   207         }
   196         fatalErrors = options.isSet("fatalEnterError");
   208         fatalErrors = options.isSet("fatalEnterError");
   197         showResolveErrors = options.isSet("showResolveErrors");
   209         showResolveErrors = options.isSet("showResolveErrors");
   198         werror = options.isSet(WERROR);
   210         werror = options.isSet(WERROR);
       
   211         fileManager = context.get(JavaFileManager.class);
   199         platformAnnotations = initPlatformAnnotations();
   212         platformAnnotations = initPlatformAnnotations();
   200 
   213 
   201         // Initialize services before any processors are initialized
   214         // Initialize services before any processors are initialized
   202         // in case processors use them.
   215         // in case processors use them.
   203         filer = new JavacFiler(context);
   216         filer = new JavacFiler(context);
   204         messager = new JavacMessager(context, this);
   217         messager = new JavacMessager(context, this);
   205         elementUtils = JavacElements.instance(context);
   218         elementUtils = JavacElements.instance(context);
   206         typeUtils = JavacTypes.instance(context);
   219         typeUtils = JavacTypes.instance(context);
       
   220         modules = Modules.instance(context);
   207         types = Types.instance(context);
   221         types = Types.instance(context);
   208         processorOptions = initProcessorOptions();
   222         processorOptions = initProcessorOptions();
   209         unmatchedProcessorOptions = initUnmatchedProcessorOptions();
   223         unmatchedProcessorOptions = initUnmatchedProcessorOptions();
   210         messages = JavacMessages.instance(context);
   224         messages = JavacMessages.instance(context);
   211         taskListener = MultiTaskListener.instance(context);
   225         taskListener = MultiTaskListener.instance(context);
   212         symtab = Symtab.instance(context);
   226         symtab = Symtab.instance(context);
   213         names = Names.instance(context);
   227         names = Names.instance(context);
   214         enter = Enter.instance(context);
   228         enter = Enter.instance(context);
   215         initialCompleter = ClassFinder.instance(context).getCompleter();
   229         initialCompleter = ClassFinder.instance(context).getCompleter();
   216         chk = Check.instance(context);
   230         chk = Check.instance(context);
   217         initProcessorClassLoader();
   231         moduleHelper = ModuleHelper.instance(context);
       
   232         initProcessorLoader();
       
   233 
       
   234         defaultModule = source.allowModules() && options.isUnset("noModules")
       
   235                 ? symtab.unnamedModule : symtab.noModule;
   218     }
   236     }
   219 
   237 
   220     public void setProcessors(Iterable<? extends Processor> processors) {
   238     public void setProcessors(Iterable<? extends Processor> processors) {
   221         Assert.checkNull(discoveredProcs);
   239         Assert.checkNull(discoveredProcs);
   222         initProcessorIterator(processors);
   240         initProcessorIterator(processors);
   232         platformAnnotations.add("java.lang.annotation.Retention");
   250         platformAnnotations.add("java.lang.annotation.Retention");
   233         platformAnnotations.add("java.lang.annotation.Target");
   251         platformAnnotations.add("java.lang.annotation.Target");
   234         return Collections.unmodifiableSet(platformAnnotations);
   252         return Collections.unmodifiableSet(platformAnnotations);
   235     }
   253     }
   236 
   254 
   237     private void initProcessorClassLoader() {
   255     private void initProcessorLoader() {
   238         JavaFileManager fileManager = context.get(JavaFileManager.class);
       
   239         try {
   256         try {
   240             // If processorpath is not explicitly set, use the classpath.
   257             if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) {
   241             processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
   258                 try {
   242                 ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH)
   259                     serviceLoader = fileManager.getServiceLoader(ANNOTATION_PROCESSOR_MODULE_PATH, Processor.class);
   243                 : fileManager.getClassLoader(CLASS_PATH);
   260                 } catch (IOException e) {
   244 
   261                     throw new Abort(e);
   245             if (processorClassLoader != null && processorClassLoader instanceof Closeable) {
   262                 }
   246                 compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
   263             } else {
       
   264                 // If processorpath is not explicitly set, use the classpath.
       
   265                 processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
       
   266                     ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH)
       
   267                     : fileManager.getClassLoader(CLASS_PATH);
       
   268 
       
   269                 moduleHelper.addExports(processorClassLoader);
       
   270 
       
   271                 if (processorClassLoader != null && processorClassLoader instanceof Closeable) {
       
   272                     compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
       
   273                 }
   247             }
   274             }
   248         } catch (SecurityException e) {
   275         } catch (SecurityException e) {
   249             processorClassLoaderException = e;
   276             processorLoaderException = e;
   250         }
   277         }
   251     }
   278     }
   252 
   279 
   253     private void initProcessorIterator(Iterable<? extends Processor> processors) {
   280     private void initProcessorIterator(Iterable<? extends Processor> processors) {
   254         Iterator<? extends Processor> processorIterator;
   281         Iterator<? extends Processor> processorIterator;
   264                 throw assertError;
   291                 throw assertError;
   265             }
   292             }
   266         } else if (processors != null) {
   293         } else if (processors != null) {
   267             processorIterator = processors.iterator();
   294             processorIterator = processors.iterator();
   268         } else {
   295         } else {
   269             String processorNames = options.get(PROCESSOR);
   296             if (processorLoaderException == null) {
   270             if (processorClassLoaderException == null) {
       
   271                 /*
   297                 /*
   272                  * If the "-processor" option is used, search the appropriate
   298                  * If the "-processor" option is used, search the appropriate
   273                  * path for the named class.  Otherwise, use a service
   299                  * path for the named class.  Otherwise, use a service
   274                  * provider mechanism to create the processor iterator.
   300                  * provider mechanism to create the processor iterator.
   275                  */
   301                  */
   276                 if (processorNames != null) {
   302                 String processorNames = options.get(PROCESSOR);
       
   303                 if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) {
       
   304                     processorIterator = (processorNames == null) ?
       
   305                             new ServiceIterator(serviceLoader, log) :
       
   306                             new NameServiceIterator(serviceLoader, log, processorNames);
       
   307                 } else if (processorNames != null) {
   277                     processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log);
   308                     processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log);
   278                 } else {
   309                 } else {
   279                     processorIterator = new ServiceIterator(processorClassLoader, log);
   310                     processorIterator = new ServiceIterator(processorClassLoader, log);
   280                 }
   311                 }
   281             } else {
   312             } else {
   284                  * Ignore the exception if, with hindsight, we didn't need it anyway
   315                  * Ignore the exception if, with hindsight, we didn't need it anyway
   285                  * (i.e. no processor was specified either explicitly, or implicitly,
   316                  * (i.e. no processor was specified either explicitly, or implicitly,
   286                  * in service configuration file.) Otherwise, we cannot continue.
   317                  * in service configuration file.) Otherwise, we cannot continue.
   287                  */
   318                  */
   288                 processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader",
   319                 processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader",
   289                         processorClassLoaderException);
   320                         processorLoaderException);
   290             }
   321             }
   291         }
   322         }
   292         PlatformDescription platformProvider = context.get(PlatformDescription.class);
   323         PlatformDescription platformProvider = context.get(PlatformDescription.class);
   293         java.util.List<Processor> platformProcessors = Collections.emptyList();
   324         java.util.List<Processor> platformProcessors = Collections.emptyList();
   294         if (platformProvider != null) {
   325         if (platformProvider != null) {
   300         List<Iterator<? extends Processor>> iterators = List.of(processorIterator,
   331         List<Iterator<? extends Processor>> iterators = List.of(processorIterator,
   301                                                                 platformProcessors.iterator());
   332                                                                 platformProcessors.iterator());
   302         Iterator<? extends Processor> compoundIterator =
   333         Iterator<? extends Processor> compoundIterator =
   303                 Iterators.createCompoundIterator(iterators, i -> i);
   334                 Iterators.createCompoundIterator(iterators, i -> i);
   304         discoveredProcs = new DiscoveredProcessors(compoundIterator);
   335         discoveredProcs = new DiscoveredProcessors(compoundIterator);
       
   336     }
       
   337 
       
   338     public <S> ServiceLoader<S> getServiceLoader(Class<S> service) {
       
   339         if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) {
       
   340             try {
       
   341                 return fileManager.getServiceLoader(ANNOTATION_PROCESSOR_MODULE_PATH, service);
       
   342             } catch (IOException e) {
       
   343                 throw new Abort(e);
       
   344             }
       
   345         } else {
       
   346             return ServiceLoader.load(service, getProcessorClassLoader());
       
   347         }
   305     }
   348     }
   306 
   349 
   307     /**
   350     /**
   308      * Returns an empty processor iterator if no processors are on the
   351      * Returns an empty processor iterator if no processors are on the
   309      * relevant path, otherwise if processors are present, logs an
   352      * relevant path, otherwise if processors are present, logs an
   314      *
   357      *
   315      * @param key The resource key to use to log an error message
   358      * @param key The resource key to use to log an error message
   316      * @param e   If non-null, pass this exception to Abort
   359      * @param e   If non-null, pass this exception to Abort
   317      */
   360      */
   318     private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) {
   361     private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) {
   319         JavaFileManager fileManager = context.get(JavaFileManager.class);
       
   320 
       
   321         if (fileManager instanceof JavacFileManager) {
   362         if (fileManager instanceof JavacFileManager) {
   322             StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager;
   363             StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager;
   323             Iterable<? extends Path> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
   364             Iterable<? extends Path> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
   324                 ? standardFileManager.getLocationAsPaths(ANNOTATION_PROCESSOR_PATH)
   365                 ? standardFileManager.getLocationAsPaths(ANNOTATION_PROCESSOR_PATH)
   325                 : standardFileManager.getLocationAsPaths(CLASS_PATH);
   366                 : standardFileManager.getLocationAsPaths(CLASS_PATH);
   353      * Use a service loader appropriate for the platform to provide an
   394      * Use a service loader appropriate for the platform to provide an
   354      * iterator over annotations processors; fails if a loader is
   395      * iterator over annotations processors; fails if a loader is
   355      * needed but unavailable.
   396      * needed but unavailable.
   356      */
   397      */
   357     private class ServiceIterator implements Iterator<Processor> {
   398     private class ServiceIterator implements Iterator<Processor> {
   358         private Iterator<Processor> iterator;
   399         Iterator<Processor> iterator;
   359         private Log log;
   400         Log log;
   360         private ServiceLoader<Processor> loader;
   401         ServiceLoader<Processor> loader;
   361 
   402 
   362         ServiceIterator(ClassLoader classLoader, Log log) {
   403         ServiceIterator(ClassLoader classLoader, Log log) {
   363             this.log = log;
   404             this.log = log;
   364             try {
   405             try {
   365                 try {
   406                 try {
   373                 log.error("proc.service.problem");
   414                 log.error("proc.service.problem");
   374                 throw new Abort(t);
   415                 throw new Abort(t);
   375             }
   416             }
   376         }
   417         }
   377 
   418 
       
   419         ServiceIterator(ServiceLoader<Processor> loader, Log log) {
       
   420             this.log = log;
       
   421             this.loader = loader;
       
   422             this.iterator = loader.iterator();
       
   423         }
       
   424 
       
   425         @Override
   378         public boolean hasNext() {
   426         public boolean hasNext() {
   379             try {
   427             try {
   380                 return iterator.hasNext();
   428                 return internalHasNext();
   381             } catch(ServiceConfigurationError sce) {
   429             } catch(ServiceConfigurationError sce) {
   382                 log.error("proc.bad.config.file", sce.getLocalizedMessage());
   430                 log.error("proc.bad.config.file", sce.getLocalizedMessage());
   383                 throw new Abort(sce);
   431                 throw new Abort(sce);
   384             } catch (Throwable t) {
   432             } catch (Throwable t) {
   385                 throw new Abort(t);
   433                 throw new Abort(t);
   386             }
   434             }
   387         }
   435         }
   388 
   436 
       
   437         boolean internalHasNext() {
       
   438             return iterator.hasNext();
       
   439         }
       
   440 
       
   441         @Override
   389         public Processor next() {
   442         public Processor next() {
   390             try {
   443             try {
   391                 return iterator.next();
   444                 return internalNext();
   392             } catch (ServiceConfigurationError sce) {
   445             } catch (ServiceConfigurationError sce) {
   393                 log.error("proc.bad.config.file", sce.getLocalizedMessage());
   446                 log.error("proc.bad.config.file", sce.getLocalizedMessage());
   394                 throw new Abort(sce);
   447                 throw new Abort(sce);
   395             } catch (Throwable t) {
   448             } catch (Throwable t) {
   396                 throw new Abort(t);
   449                 throw new Abort(t);
   397             }
   450             }
   398         }
   451         }
   399 
   452 
       
   453         Processor internalNext() {
       
   454             return iterator.next();
       
   455         }
       
   456 
       
   457         @Override
   400         public void remove() {
   458         public void remove() {
   401             throw new UnsupportedOperationException();
   459             throw new UnsupportedOperationException();
   402         }
   460         }
   403 
   461 
   404         public void close() {
   462         public void close() {
   410                 }
   468                 }
   411             }
   469             }
   412         }
   470         }
   413     }
   471     }
   414 
   472 
       
   473     private class NameServiceIterator extends ServiceIterator {
       
   474         private Map<String, Processor> namedProcessorsMap = new HashMap<>();;
       
   475         private Iterator<String> processorNames = null;
       
   476         private Processor nextProc = null;
       
   477 
       
   478         public NameServiceIterator(ServiceLoader<Processor> loader, Log log, String theNames) {
       
   479             super(loader, log);
       
   480             this.processorNames = Arrays.asList(theNames.split(",")).iterator();
       
   481         }
       
   482 
       
   483         @Override
       
   484         boolean internalHasNext() {
       
   485             if (nextProc != null) {
       
   486                 return true;
       
   487             }
       
   488             if (!processorNames.hasNext()) {
       
   489                 namedProcessorsMap = null;
       
   490                 return false;
       
   491             }
       
   492             String processorName = processorNames.next();
       
   493             Processor theProcessor = namedProcessorsMap.get(processorName);
       
   494             if (theProcessor != null) {
       
   495                 namedProcessorsMap.remove(processorName);
       
   496                 nextProc = theProcessor;
       
   497                 return true;
       
   498             } else {
       
   499                 while (iterator.hasNext()) {
       
   500                     theProcessor = iterator.next();
       
   501                     String name = theProcessor.getClass().getName();
       
   502                     if (name.equals(processorName)) {
       
   503                         nextProc = theProcessor;
       
   504                         return true;
       
   505                     } else {
       
   506                         namedProcessorsMap.put(name, theProcessor);
       
   507                     }
       
   508                 }
       
   509                 log.error(Errors.ProcProcessorNotFound(processorName));
       
   510                 return false;
       
   511             }
       
   512         }
       
   513 
       
   514         @Override
       
   515         Processor internalNext() {
       
   516             if (hasNext()) {
       
   517                 Processor p = nextProc;
       
   518                 nextProc = null;
       
   519                 return p;
       
   520             } else {
       
   521                 throw new NoSuchElementException();
       
   522             }
       
   523         }
       
   524     }
   415 
   525 
   416     private static class NameProcessIterator implements Iterator<Processor> {
   526     private static class NameProcessIterator implements Iterator<Processor> {
   417         Processor nextProc = null;
   527         Processor nextProc = null;
   418         Iterator<String> names;
   528         Iterator<String> names;
   419         ClassLoader processorCL;
   529         ClassLoader processorCL;
   435                     String processorName = names.next();
   545                     String processorName = names.next();
   436 
   546 
   437                     Processor processor;
   547                     Processor processor;
   438                     try {
   548                     try {
   439                         try {
   549                         try {
       
   550                             Class<?> processorClass = processorCL.loadClass(processorName);
       
   551                             ensureReadable(processorClass);
   440                             processor =
   552                             processor =
   441                                 (Processor) (processorCL.loadClass(processorName).newInstance());
   553                                 (Processor) (processorClass.newInstance());
   442                         } catch (ClassNotFoundException cnfe) {
   554                         } catch (ClassNotFoundException cnfe) {
   443                             log.error("proc.processor.not.found", processorName);
   555                             log.error("proc.processor.not.found", processorName);
   444                             return false;
   556                             return false;
   445                         } catch (ClassCastException cce) {
   557                         } catch (ClassCastException cce) {
   446                             log.error("proc.processor.wrong.type", processorName);
   558                             log.error("proc.processor.wrong.type", processorName);
   471         }
   583         }
   472 
   584 
   473         public void remove () {
   585         public void remove () {
   474             throw new UnsupportedOperationException();
   586             throw new UnsupportedOperationException();
   475         }
   587         }
       
   588 
       
   589         /**
       
   590          * Ensures that the module of the given class is readable to this
       
   591          * module.
       
   592          */
       
   593         private void ensureReadable(Class<?> targetClass) {
       
   594             try {
       
   595                 Method getModuleMethod = Class.class.getMethod("getModule");
       
   596                 Object thisModule = getModuleMethod.invoke(this.getClass());
       
   597                 Object targetModule = getModuleMethod.invoke(targetClass);
       
   598 
       
   599                 Class<?> moduleClass = getModuleMethod.getReturnType();
       
   600                 Method addReadsMethod = moduleClass.getMethod("addReads", moduleClass);
       
   601                 addReadsMethod.invoke(thisModule, targetModule);
       
   602             } catch (NoSuchMethodException e) {
       
   603                 // ignore
       
   604             } catch (Exception e) {
       
   605                 throw new InternalError(e);
       
   606             }
       
   607         }
   476     }
   608     }
   477 
   609 
   478     public boolean atLeastOneProcessor() {
   610     public boolean atLeastOneProcessor() {
   479         return discoveredProcs.iterator().hasNext();
   611         return discoveredProcs.iterator().hasNext();
   480     }
   612     }
   603     }
   735     }
   604 
   736 
   605     // TODO: These two classes can probably be rewritten better...
   737     // TODO: These two classes can probably be rewritten better...
   606     /**
   738     /**
   607      * This class holds information about the processors that have
   739      * This class holds information about the processors that have
   608      * been discoverd so far as well as the means to discover more, if
   740      * been discovered so far as well as the means to discover more, if
   609      * necessary.  A single iterator should be used per round of
   741      * necessary.  A single iterator should be used per round of
   610      * annotation processing.  The iterator first visits already
   742      * annotation processing.  The iterator first visits already
   611      * discovered processors then fails over to the service provider
   743      * discovered processors then fails over to the service provider
   612      * mechanism if additional queries are made.
   744      * mechanism if additional queries are made.
   613      */
   745      */
   998                 Name name = names.fromString(entry.getKey());
  1130                 Name name = names.fromString(entry.getKey());
   999                 JavaFileObject file = entry.getValue();
  1131                 JavaFileObject file = entry.getValue();
  1000                 if (file.getKind() != JavaFileObject.Kind.CLASS)
  1132                 if (file.getKind() != JavaFileObject.Kind.CLASS)
  1001                     throw new AssertionError(file);
  1133                     throw new AssertionError(file);
  1002                 ClassSymbol cs;
  1134                 ClassSymbol cs;
       
  1135                 // TODO: for now, we assume that generated code is in a default module;
       
  1136                 // in time, we need a way to be able to specify the module for generated code
  1003                 if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) {
  1137                 if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) {
  1004                     Name packageName = Convert.packagePart(name);
  1138                     Name packageName = Convert.packagePart(name);
  1005                     PackageSymbol p = symtab.enterPackage(packageName);
  1139                     PackageSymbol p = symtab.enterPackage(defaultModule, packageName);
  1006                     if (p.package_info == null)
  1140                     if (p.package_info == null)
  1007                         p.package_info = symtab.enterClass(Convert.shortName(name), p);
  1141                         p.package_info = symtab.enterClass(defaultModule, Convert.shortName(name), p);
  1008                     cs = p.package_info;
  1142                     cs = p.package_info;
  1009                     cs.reset();
  1143                     cs.reset();
  1010                     if (cs.classfile == null)
  1144                     if (cs.classfile == null)
  1011                         cs.classfile = file;
  1145                         cs.classfile = file;
  1012                     cs.completer = initialCompleter;
  1146                     cs.completer = initialCompleter;
  1013                 } else {
  1147                 } else {
  1014                     cs = symtab.enterClass(name);
  1148                     cs = symtab.enterClass(defaultModule, name);
  1015                     cs.reset();
  1149                     cs.reset();
  1016                     cs.classfile = file;
  1150                     cs.classfile = file;
  1017                     cs.completer = initialCompleter;
  1151                     cs.completer = initialCompleter;
       
  1152                     cs.owner.members().enter(cs); //XXX - OverwriteBetweenCompilations; syms.getClass is not sufficient anymore
  1018                 }
  1153                 }
  1019                 list = list.prepend(cs);
  1154                 list = list.prepend(cs);
  1020             }
  1155             }
  1021             return list.reverse();
  1156             return list.reverse();
  1022         }
  1157         }
  1023 
  1158 
  1024         /** Enter a set of syntax trees. */
  1159         /** Enter a set of syntax trees. */
  1025         private void enterTrees(List<JCCompilationUnit> roots) {
  1160         private void enterTrees(List<JCCompilationUnit> roots) {
  1026             compiler.enterTrees(roots);
  1161             compiler.enterTrees(compiler.initModules(roots));
  1027         }
  1162         }
  1028 
  1163 
  1029         /** Run a processing round. */
  1164         /** Run a processing round. */
  1030         void run(boolean lastRound, boolean errorStatus) {
  1165         void run(boolean lastRound, boolean errorStatus) {
  1031             printRoundInfo(lastRound);
  1166             printRoundInfo(lastRound);
  1097             chk.newRound();
  1232             chk.newRound();
  1098             enter.newRound();
  1233             enter.newRound();
  1099             filer.newRound();
  1234             filer.newRound();
  1100             messager.newRound();
  1235             messager.newRound();
  1101             compiler.newRound();
  1236             compiler.newRound();
       
  1237             modules.newRound();
  1102             types.newRound();
  1238             types.newRound();
  1103 
  1239 
  1104             boolean foundError = false;
  1240             boolean foundError = false;
  1105 
  1241 
  1106             for (ClassSymbol cs : symtab.classes.values()) {
  1242             for (ClassSymbol cs : symtab.getAllClasses()) {
  1107                 if (cs.kind == ERR) {
  1243                 if (cs.kind == ERR) {
  1108                     foundError = true;
  1244                     foundError = true;
  1109                     break;
  1245                     break;
  1110                 }
  1246                 }
  1111             }
  1247             }
  1112 
  1248 
  1113             if (foundError) {
  1249             if (foundError) {
  1114                 for (ClassSymbol cs : symtab.classes.values()) {
  1250                 for (ClassSymbol cs : symtab.getAllClasses()) {
  1115                     if (cs.classfile != null || cs.kind == ERR) {
  1251                     if (cs.classfile != null || cs.kind == ERR) {
  1116                         cs.reset();
  1252                         cs.reset();
  1117                         cs.type = new ClassType(cs.type.getEnclosingType(), null, cs);
  1253                         cs.type = new ClassType(cs.type.getEnclosingType(), null, cs);
  1118                         if (cs.isCompleted()) {
  1254                         if (cs.isCompleted()) {
  1119                             cs.completer = initialCompleter;
  1255                             cs.completer = initialCompleter;
  1348                     if (node.packge.package_info != null) {
  1484                     if (node.packge.package_info != null) {
  1349                         node.packge.package_info.reset();
  1485                         node.packge.package_info.reset();
  1350                     }
  1486                     }
  1351                     node.packge.reset();
  1487                     node.packge.reset();
  1352                 }
  1488                 }
       
  1489                 boolean isModuleInfo = node.sourcefile.isNameCompatible("module-info", Kind.SOURCE);
       
  1490                 if (isModuleInfo) {
       
  1491                     node.modle.reset();
       
  1492                     node.modle.completer = sym -> modules.enter(List.of(node), node.modle.module_info);
       
  1493                     node.modle.module_info.reset();
       
  1494                     node.modle.module_info.members_field = WriteableScope.create(node.modle.module_info);
       
  1495                 }
  1353                 node.packge = null;
  1496                 node.packge = null;
  1354                 topLevel = node;
  1497                 topLevel = node;
  1355                 try {
  1498                 try {
  1356                     super.visitTopLevel(node);
  1499                     super.visitTopLevel(node);
  1357                 } finally {
  1500                 } finally {