langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java
changeset 42815 050370edaade
parent 40232 4995ab1a4558
child 43368 cabe410a7a5c
equal deleted inserted replaced
42814:058fc03646d9 42815:050370edaade
    49 
    49 
    50 import static javax.tools.StandardLocation.SOURCE_OUTPUT;
    50 import static javax.tools.StandardLocation.SOURCE_OUTPUT;
    51 import static javax.tools.StandardLocation.CLASS_OUTPUT;
    51 import static javax.tools.StandardLocation.CLASS_OUTPUT;
    52 
    52 
    53 import com.sun.tools.javac.code.Lint;
    53 import com.sun.tools.javac.code.Lint;
       
    54 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
       
    55 import com.sun.tools.javac.code.Symtab;
       
    56 import com.sun.tools.javac.comp.Modules;
    54 import com.sun.tools.javac.util.*;
    57 import com.sun.tools.javac.util.*;
    55 import com.sun.tools.javac.util.DefinedBy.Api;
    58 import com.sun.tools.javac.util.DefinedBy.Api;
    56 
    59 
    57 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
    60 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
    58 
    61 
   112     /**
   115     /**
   113      * Wrap a JavaFileObject to manage writing by the Filer.
   116      * Wrap a JavaFileObject to manage writing by the Filer.
   114      */
   117      */
   115     private class FilerOutputFileObject extends ForwardingFileObject<FileObject> {
   118     private class FilerOutputFileObject extends ForwardingFileObject<FileObject> {
   116         private boolean opened = false;
   119         private boolean opened = false;
       
   120         private ModuleSymbol mod;
   117         private String name;
   121         private String name;
   118 
   122 
   119         FilerOutputFileObject(String name, FileObject fileObject) {
   123         FilerOutputFileObject(ModuleSymbol mod, String name, FileObject fileObject) {
   120             super(fileObject);
   124             super(fileObject);
       
   125             this.mod = mod;
   121             this.name = name;
   126             this.name = name;
   122         }
   127         }
   123 
   128 
   124         @Override @DefinedBy(Api.COMPILER)
   129         @Override @DefinedBy(Api.COMPILER)
   125         public synchronized OutputStream openOutputStream() throws IOException {
   130         public synchronized OutputStream openOutputStream() throws IOException {
   126             if (opened)
   131             if (opened)
   127                 throw new IOException(ALREADY_OPENED);
   132                 throw new IOException(ALREADY_OPENED);
   128             opened = true;
   133             opened = true;
   129             return new FilerOutputStream(name, fileObject);
   134             return new FilerOutputStream(mod, name, fileObject);
   130         }
   135         }
   131 
   136 
   132         @Override @DefinedBy(Api.COMPILER)
   137         @Override @DefinedBy(Api.COMPILER)
   133         public synchronized Writer openWriter() throws IOException {
   138         public synchronized Writer openWriter() throws IOException {
   134             if (opened)
   139             if (opened)
   135                 throw new IOException(ALREADY_OPENED);
   140                 throw new IOException(ALREADY_OPENED);
   136             opened = true;
   141             opened = true;
   137             return new FilerWriter(name, fileObject);
   142             return new FilerWriter(mod, name, fileObject);
   138         }
   143         }
   139 
   144 
   140         // Three anti-literacy methods
   145         // Three anti-literacy methods
   141         @Override @DefinedBy(Api.COMPILER)
   146         @Override @DefinedBy(Api.COMPILER)
   142         public InputStream openInputStream() throws IOException {
   147         public InputStream openInputStream() throws IOException {
   159         }
   164         }
   160     }
   165     }
   161 
   166 
   162     private class FilerOutputJavaFileObject extends FilerOutputFileObject implements JavaFileObject {
   167     private class FilerOutputJavaFileObject extends FilerOutputFileObject implements JavaFileObject {
   163         private final JavaFileObject javaFileObject;
   168         private final JavaFileObject javaFileObject;
   164         FilerOutputJavaFileObject(String name, JavaFileObject javaFileObject) {
   169         FilerOutputJavaFileObject(ModuleSymbol mod, String name, JavaFileObject javaFileObject) {
   165             super(name, javaFileObject);
   170             super(mod, name, javaFileObject);
   166             this.javaFileObject = javaFileObject;
   171             this.javaFileObject = javaFileObject;
   167         }
   172         }
   168 
   173 
   169         @DefinedBy(Api.COMPILER)
   174         @DefinedBy(Api.COMPILER)
   170         public JavaFileObject.Kind getKind() {
   175         public JavaFileObject.Kind getKind() {
   246      * Wrap a {@code OutputStream} returned from the {@code
   251      * Wrap a {@code OutputStream} returned from the {@code
   247      * JavaFileManager} to properly register source or class files
   252      * JavaFileManager} to properly register source or class files
   248      * when they are closed.
   253      * when they are closed.
   249      */
   254      */
   250     private class FilerOutputStream extends FilterOutputStream {
   255     private class FilerOutputStream extends FilterOutputStream {
       
   256         ModuleSymbol mod;
   251         String typeName;
   257         String typeName;
   252         FileObject fileObject;
   258         FileObject fileObject;
   253         boolean closed = false;
   259         boolean closed = false;
   254 
   260 
   255         /**
   261         /**
   256          * @param typeName name of class or {@code null} if just a
   262          * @param typeName name of class or {@code null} if just a
   257          * binary file
   263          * binary file
   258          */
   264          */
   259         FilerOutputStream(String typeName, FileObject fileObject) throws IOException {
   265         FilerOutputStream(ModuleSymbol mod, String typeName, FileObject fileObject) throws IOException {
   260             super(fileObject.openOutputStream());
   266             super(fileObject.openOutputStream());
       
   267             this.mod = mod;
   261             this.typeName = typeName;
   268             this.typeName = typeName;
   262             this.fileObject = fileObject;
   269             this.fileObject = fileObject;
   263         }
   270         }
   264 
   271 
   265         public synchronized void close() throws IOException {
   272         public synchronized void close() throws IOException {
   268                 /*
   275                 /*
   269                  * If an IOException occurs when closing the underlying
   276                  * If an IOException occurs when closing the underlying
   270                  * stream, still try to process the file.
   277                  * stream, still try to process the file.
   271                  */
   278                  */
   272 
   279 
   273                 closeFileObject(typeName, fileObject);
   280                 closeFileObject(mod, typeName, fileObject);
   274                 out.close();
   281                 out.close();
   275             }
   282             }
   276         }
   283         }
   277     }
   284     }
   278 
   285 
   280      * Wrap a {@code Writer} returned from the {@code JavaFileManager}
   287      * Wrap a {@code Writer} returned from the {@code JavaFileManager}
   281      * to properly register source or class files when they are
   288      * to properly register source or class files when they are
   282      * closed.
   289      * closed.
   283      */
   290      */
   284     private class FilerWriter extends FilterWriter {
   291     private class FilerWriter extends FilterWriter {
       
   292         ModuleSymbol mod;
   285         String typeName;
   293         String typeName;
   286         FileObject fileObject;
   294         FileObject fileObject;
   287         boolean closed = false;
   295         boolean closed = false;
   288 
   296 
   289         /**
   297         /**
   290          * @param fileObject the fileObject to be written to
   298          * @param fileObject the fileObject to be written to
   291          * @param typeName name of source file or {@code null} if just a
   299          * @param typeName name of source file or {@code null} if just a
   292          * text file
   300          * text file
   293          */
   301          */
   294         FilerWriter(String typeName, FileObject fileObject) throws IOException {
   302         FilerWriter(ModuleSymbol mod, String typeName, FileObject fileObject) throws IOException {
   295             super(fileObject.openWriter());
   303             super(fileObject.openWriter());
       
   304             this.mod = mod;
   296             this.typeName = typeName;
   305             this.typeName = typeName;
   297             this.fileObject = fileObject;
   306             this.fileObject = fileObject;
   298         }
   307         }
   299 
   308 
   300         public synchronized void close() throws IOException {
   309         public synchronized void close() throws IOException {
   303                 /*
   312                 /*
   304                  * If an IOException occurs when closing the underlying
   313                  * If an IOException occurs when closing the underlying
   305                  * Writer, still try to process the file.
   314                  * Writer, still try to process the file.
   306                  */
   315                  */
   307 
   316 
   308                 closeFileObject(typeName, fileObject);
   317                 closeFileObject(mod, typeName, fileObject);
   309                 out.close();
   318                 out.close();
   310             }
   319             }
   311         }
   320         }
   312     }
   321     }
   313 
   322 
   314     JavaFileManager fileManager;
   323     JavaFileManager fileManager;
   315     Log log;
   324     Log log;
       
   325     Modules modules;
       
   326     Names names;
       
   327     Symtab syms;
   316     Context context;
   328     Context context;
   317     boolean lastRound;
   329     boolean lastRound;
   318 
   330 
   319     private final boolean lint;
   331     private final boolean lint;
   320 
   332 
   338     /**
   350     /**
   339      * Names and class files of the class files closed in this round.
   351      * Names and class files of the class files closed in this round.
   340      * This set must be synchronized.  Its iterators should preserve
   352      * This set must be synchronized.  Its iterators should preserve
   341      * insertion order.
   353      * insertion order.
   342      */
   354      */
   343     private final Map<String, JavaFileObject> generatedClasses;
   355     private final Map<ModuleSymbol, Map<String, JavaFileObject>> generatedClasses;
   344 
   356 
   345     /**
   357     /**
   346      * JavaFileObjects for source files closed in this round.  This
   358      * JavaFileObjects for source files closed in this round.  This
   347      * set must be synchronized.  Its iterators should preserve
   359      * set must be synchronized.  Its iterators should preserve
   348      * insertion order.
   360      * insertion order.
   351 
   363 
   352     /**
   364     /**
   353      * Names of all created source files.  Its iterators should
   365      * Names of all created source files.  Its iterators should
   354      * preserve insertion order.
   366      * preserve insertion order.
   355      */
   367      */
   356     private final Set<String> aggregateGeneratedSourceNames;
   368     private final Set<Pair<ModuleSymbol, String>> aggregateGeneratedSourceNames;
   357 
   369 
   358     /**
   370     /**
   359      * Names of all created class files.  Its iterators should
   371      * Names of all created class files.  Its iterators should
   360      * preserve insertion order.
   372      * preserve insertion order.
   361      */
   373      */
   362     private final Set<String> aggregateGeneratedClassNames;
   374     private final Set<Pair<ModuleSymbol, String>> aggregateGeneratedClassNames;
   363 
   375 
   364 
   376 
   365     JavacFiler(Context context) {
   377     JavacFiler(Context context) {
   366         this.context = context;
   378         this.context = context;
   367         fileManager = context.get(JavaFileManager.class);
   379         fileManager = context.get(JavaFileManager.class);
   368 
   380 
   369         log = Log.instance(context);
   381         log = Log.instance(context);
       
   382         modules = Modules.instance(context);
       
   383         names = Names.instance(context);
       
   384         syms = Symtab.instance(context);
   370 
   385 
   371         fileObjectHistory = synchronizedSet(new LinkedHashSet<FileObject>());
   386         fileObjectHistory = synchronizedSet(new LinkedHashSet<FileObject>());
   372         generatedSourceNames = synchronizedSet(new LinkedHashSet<String>());
   387         generatedSourceNames = synchronizedSet(new LinkedHashSet<String>());
   373         generatedSourceFileObjects = synchronizedSet(new LinkedHashSet<JavaFileObject>());
   388         generatedSourceFileObjects = synchronizedSet(new LinkedHashSet<JavaFileObject>());
   374 
   389 
   375         generatedClasses = synchronizedMap(new LinkedHashMap<String, JavaFileObject>());
   390         generatedClasses = synchronizedMap(new LinkedHashMap<>());
   376 
   391 
   377         openTypeNames  = synchronizedSet(new LinkedHashSet<String>());
   392         openTypeNames  = synchronizedSet(new LinkedHashSet<String>());
   378 
   393 
   379         aggregateGeneratedSourceNames = new LinkedHashSet<>();
   394         aggregateGeneratedSourceNames = new LinkedHashSet<>();
   380         aggregateGeneratedClassNames  = new LinkedHashSet<>();
   395         aggregateGeneratedClassNames  = new LinkedHashSet<>();
   381 
   396 
   382         lint = (Lint.instance(context)).isEnabled(PROCESSING);
   397         lint = (Lint.instance(context)).isEnabled(PROCESSING);
   383     }
   398     }
   384 
   399 
   385     @DefinedBy(Api.ANNOTATION_PROCESSING)
   400     @Override @DefinedBy(Api.ANNOTATION_PROCESSING)
   386     public JavaFileObject createSourceFile(CharSequence name,
   401     public JavaFileObject createSourceFile(CharSequence nameAndModule,
   387                                            Element... originatingElements) throws IOException {
   402                                            Element... originatingElements) throws IOException {
   388         return createSourceOrClassFile(true, name.toString());
   403         Pair<ModuleSymbol, String> moduleAndClass = checkOrInferModule(nameAndModule);
   389     }
   404         return createSourceOrClassFile(moduleAndClass.fst, true, moduleAndClass.snd);
   390 
   405     }
   391     @DefinedBy(Api.ANNOTATION_PROCESSING)
   406 
   392     public JavaFileObject createClassFile(CharSequence name,
   407     @Override @DefinedBy(Api.ANNOTATION_PROCESSING)
   393                                            Element... originatingElements) throws IOException {
   408     public JavaFileObject createClassFile(CharSequence nameAndModule,
   394         return createSourceOrClassFile(false, name.toString());
   409                                           Element... originatingElements) throws IOException {
   395     }
   410         Pair<ModuleSymbol, String> moduleAndClass = checkOrInferModule(nameAndModule);
   396 
   411         return createSourceOrClassFile(moduleAndClass.fst, false, moduleAndClass.snd);
   397     private JavaFileObject createSourceOrClassFile(boolean isSourceFile, String name) throws IOException {
   412     }
       
   413 
       
   414     private Pair<ModuleSymbol, String> checkOrInferModule(CharSequence moduleAndPkg) throws FilerException {
       
   415         String moduleAndPkgString = moduleAndPkg.toString();
       
   416         int slash = moduleAndPkgString.indexOf('/');
       
   417 
       
   418         if (slash != (-1)) {
       
   419             //module name specified:
       
   420             String module = moduleAndPkgString.substring(0, slash);
       
   421 
       
   422             ModuleSymbol explicitModule = syms.getModule(names.fromString(module));
       
   423 
       
   424             if (explicitModule == null) {
       
   425                 throw new FilerException("Module: " + module + " does not exist.");
       
   426             }
       
   427 
       
   428             if (!modules.isRootModule(explicitModule)) {
       
   429                 throw new FilerException("Cannot write to the given module!");
       
   430             }
       
   431 
       
   432             return Pair.of(explicitModule, moduleAndPkgString.substring(slash + 1));
       
   433         } else {
       
   434             if (modules.multiModuleMode) {
       
   435                 throw new FilerException("No module to write to specified!");
       
   436             }
       
   437 
       
   438             return Pair.of(modules.getDefaultModule(), moduleAndPkgString);
       
   439         }
       
   440     }
       
   441 
       
   442     private JavaFileObject createSourceOrClassFile(ModuleSymbol mod, boolean isSourceFile, String name) throws IOException {
       
   443         Assert.checkNonNull(mod);
       
   444 
   398         if (lint) {
   445         if (lint) {
   399             int periodIndex = name.lastIndexOf(".");
   446             int periodIndex = name.lastIndexOf(".");
   400             if (periodIndex != -1) {
   447             if (periodIndex != -1) {
   401                 String base = name.substring(periodIndex);
   448                 String base = name.substring(periodIndex);
   402                 String extn = (isSourceFile ? ".java" : ".class");
   449                 String extn = (isSourceFile ? ".java" : ".class");
   403                 if (base.equals(extn))
   450                 if (base.equals(extn))
   404                     log.warning("proc.suspicious.class.name", name, extn);
   451                     log.warning("proc.suspicious.class.name", name, extn);
   405             }
   452             }
   406         }
   453         }
   407         checkNameAndExistence(name, isSourceFile);
   454         checkNameAndExistence(mod, name, isSourceFile);
   408         Location loc = (isSourceFile ? SOURCE_OUTPUT : CLASS_OUTPUT);
   455         Location loc = (isSourceFile ? SOURCE_OUTPUT : CLASS_OUTPUT);
       
   456 
       
   457         if (modules.multiModuleMode) {
       
   458             loc = this.fileManager.getLocationForModule(loc, mod.name.toString());
       
   459         }
   409         JavaFileObject.Kind kind = (isSourceFile ?
   460         JavaFileObject.Kind kind = (isSourceFile ?
   410                                     JavaFileObject.Kind.SOURCE :
   461                                     JavaFileObject.Kind.SOURCE :
   411                                     JavaFileObject.Kind.CLASS);
   462                                     JavaFileObject.Kind.CLASS);
   412 
   463 
   413         JavaFileObject fileObject =
   464         JavaFileObject fileObject =
   416 
   467 
   417         if (lastRound)
   468         if (lastRound)
   418             log.warning("proc.file.create.last.round", name);
   469             log.warning("proc.file.create.last.round", name);
   419 
   470 
   420         if (isSourceFile)
   471         if (isSourceFile)
   421             aggregateGeneratedSourceNames.add(name);
   472             aggregateGeneratedSourceNames.add(Pair.of(mod, name));
   422         else
   473         else
   423             aggregateGeneratedClassNames.add(name);
   474             aggregateGeneratedClassNames.add(Pair.of(mod, name));
   424         openTypeNames.add(name);
   475         openTypeNames.add(name);
   425 
   476 
   426         return new FilerOutputJavaFileObject(name, fileObject);
   477         return new FilerOutputJavaFileObject(mod, name, fileObject);
   427     }
   478     }
   428 
   479 
   429     @DefinedBy(Api.ANNOTATION_PROCESSING)
   480     @Override @DefinedBy(Api.ANNOTATION_PROCESSING)
   430     public FileObject createResource(JavaFileManager.Location location,
   481     public FileObject createResource(JavaFileManager.Location location,
   431                                      CharSequence pkg,
   482                                      CharSequence moduleAndPkg,
   432                                      CharSequence relativeName,
   483                                      CharSequence relativeName,
   433                                      Element... originatingElements) throws IOException {
   484                                      Element... originatingElements) throws IOException {
       
   485         Pair<ModuleSymbol, String> moduleAndPackage = checkOrInferModule(moduleAndPkg);
       
   486         ModuleSymbol msym = moduleAndPackage.fst;
       
   487         String pkg = moduleAndPackage.snd;
       
   488 
   434         locationCheck(location);
   489         locationCheck(location);
       
   490 
       
   491         if (modules.multiModuleMode) {
       
   492             Assert.checkNonNull(msym);
       
   493             location = this.fileManager.getLocationForModule(location, msym.name.toString());
       
   494         }
   435 
   495 
   436         String strPkg = pkg.toString();
   496         String strPkg = pkg.toString();
   437         if (strPkg.length() > 0)
   497         if (strPkg.length() > 0)
   438             checkName(strPkg);
   498             checkName(strPkg);
   439 
   499 
   441             fileManager.getFileForOutput(location, strPkg,
   501             fileManager.getFileForOutput(location, strPkg,
   442                                          relativeName.toString(), null);
   502                                          relativeName.toString(), null);
   443         checkFileReopening(fileObject, true);
   503         checkFileReopening(fileObject, true);
   444 
   504 
   445         if (fileObject instanceof JavaFileObject)
   505         if (fileObject instanceof JavaFileObject)
   446             return new FilerOutputJavaFileObject(null, (JavaFileObject)fileObject);
   506             return new FilerOutputJavaFileObject(msym, null, (JavaFileObject)fileObject);
   447         else
   507         else
   448             return new FilerOutputFileObject(null, fileObject);
   508             return new FilerOutputFileObject(msym, null, fileObject);
   449     }
   509     }
   450 
   510 
   451     private void locationCheck(JavaFileManager.Location location) {
   511     private void locationCheck(JavaFileManager.Location location) {
   452         if (location instanceof StandardLocation) {
   512         if (location instanceof StandardLocation) {
   453             StandardLocation stdLoc = (StandardLocation) location;
   513             StandardLocation stdLoc = (StandardLocation) location;
   455                 throw new IllegalArgumentException("Resource creation not supported in location " +
   515                 throw new IllegalArgumentException("Resource creation not supported in location " +
   456                                                    stdLoc);
   516                                                    stdLoc);
   457         }
   517         }
   458     }
   518     }
   459 
   519 
   460     @DefinedBy(Api.ANNOTATION_PROCESSING)
   520     @Override @DefinedBy(Api.ANNOTATION_PROCESSING)
   461     public FileObject getResource(JavaFileManager.Location location,
   521     public FileObject getResource(JavaFileManager.Location location,
   462                                   CharSequence pkg,
   522                                   CharSequence moduleAndPkg,
   463                                   CharSequence relativeName) throws IOException {
   523                                   CharSequence relativeName) throws IOException {
   464         String strPkg = pkg.toString();
   524         Pair<ModuleSymbol, String> moduleAndPackage = checkOrInferModule(moduleAndPkg);
   465         if (strPkg.length() > 0)
   525         ModuleSymbol msym = moduleAndPackage.fst;
   466             checkName(strPkg);
   526         String pkg = moduleAndPackage.snd;
       
   527 
       
   528         if (modules.multiModuleMode) {
       
   529             Assert.checkNonNull(msym);
       
   530             location = this.fileManager.getLocationForModule(location, msym.name.toString());
       
   531         }
       
   532 
       
   533         if (pkg.length() > 0)
       
   534             checkName(pkg);
   467 
   535 
   468         // TODO: Only support reading resources in selected output
   536         // TODO: Only support reading resources in selected output
   469         // locations?  Only allow reading of non-source, non-class
   537         // locations?  Only allow reading of non-source, non-class
   470         // files from the supported input locations?
   538         // files from the supported input locations?
   471 
   539 
   476         // with more than one component. So, for now, we use a hybrid
   544         // with more than one component. So, for now, we use a hybrid
   477         // invocation.
   545         // invocation.
   478         FileObject fileObject;
   546         FileObject fileObject;
   479         if (location.isOutputLocation()) {
   547         if (location.isOutputLocation()) {
   480             fileObject = fileManager.getFileForOutput(location,
   548             fileObject = fileManager.getFileForOutput(location,
   481                     pkg.toString(),
   549                     pkg,
   482                     relativeName.toString(),
   550                     relativeName.toString(),
   483                     null);
   551                     null);
   484         } else {
   552         } else {
   485             fileObject = fileManager.getFileForInput(location,
   553             fileObject = fileManager.getFileForInput(location,
   486                     pkg.toString(),
   554                     pkg,
   487                     relativeName.toString());
   555                     relativeName.toString());
   488         }
   556         }
   489         if (fileObject == null) {
   557         if (fileObject == null) {
   490             String name = (pkg.length() == 0)
   558             String name = (pkg.length() == 0)
   491                     ? relativeName.toString() : (pkg + "/" + relativeName);
   559                     ? relativeName.toString() : (pkg + "/" + relativeName);
   522             String simple = name.substring(periodIndex+1);
   590             String simple = name.substring(periodIndex+1);
   523             return SourceVersion.isName(prefix) && simple.equals(PKG_INFO);
   591             return SourceVersion.isName(prefix) && simple.equals(PKG_INFO);
   524         }
   592         }
   525     }
   593     }
   526 
   594 
   527     private void checkNameAndExistence(String typename, boolean allowUnnamedPackageInfo) throws FilerException {
   595     private void checkNameAndExistence(ModuleSymbol mod, String typename, boolean allowUnnamedPackageInfo) throws FilerException {
   528         // TODO: Check if type already exists on source or class path?
   596         // TODO: Check if type already exists on source or class path?
   529         // If so, use warning message key proc.type.already.exists
   597         // If so, use warning message key proc.type.already.exists
   530         checkName(typename, allowUnnamedPackageInfo);
   598         checkName(typename, allowUnnamedPackageInfo);
   531         if (aggregateGeneratedSourceNames.contains(typename) ||
   599         if (aggregateGeneratedSourceNames.contains(Pair.of(mod, typename)) ||
   532             aggregateGeneratedClassNames.contains(typename)) {
   600             aggregateGeneratedClassNames.contains(Pair.of(mod, typename))) {
   533             if (lint)
   601             if (lint)
   534                 log.warning("proc.type.recreate", typename);
   602                 log.warning("proc.type.recreate", typename);
   535             throw new FilerException("Attempt to recreate a file for type " + typename);
   603             throw new FilerException("Attempt to recreate a file for type " + typename);
       
   604         }
       
   605         if (!mod.isUnnamed() && !typename.contains(".")) {
       
   606             throw new FilerException("Attempt to create a type in unnamed package of a named module: " + typename);
   536         }
   607         }
   537     }
   608     }
   538 
   609 
   539     /**
   610     /**
   540      * Check to see if the file has already been opened; if so, throw
   611      * Check to see if the file has already been opened; if so, throw
   563 
   634 
   564     public Set<JavaFileObject> getGeneratedSourceFileObjects() {
   635     public Set<JavaFileObject> getGeneratedSourceFileObjects() {
   565         return generatedSourceFileObjects;
   636         return generatedSourceFileObjects;
   566     }
   637     }
   567 
   638 
   568     public Map<String, JavaFileObject> getGeneratedClasses() {
   639     public Map<ModuleSymbol, Map<String, JavaFileObject>> getGeneratedClasses() {
   569         return generatedClasses;
   640         return generatedClasses;
   570     }
   641     }
   571 
   642 
   572     public void warnIfUnclosedFiles() {
   643     public void warnIfUnclosedFiles() {
   573         if (!openTypeNames.isEmpty())
   644         if (!openTypeNames.isEmpty())
   619 
   690 
   620     /**
   691     /**
   621      * Upon close, register files opened by create{Source, Class}File
   692      * Upon close, register files opened by create{Source, Class}File
   622      * for annotation processing.
   693      * for annotation processing.
   623      */
   694      */
   624     private void closeFileObject(String typeName, FileObject fileObject) {
   695     private void closeFileObject(ModuleSymbol mod, String typeName, FileObject fileObject) {
   625         /*
   696         /*
   626          * If typeName is non-null, the file object was opened as a
   697          * If typeName is non-null, the file object was opened as a
   627          * source or class file by the user.  If a file was opened as
   698          * source or class file by the user.  If a file was opened as
   628          * a resource, typeName will be null and the file is *not*
   699          * a resource, typeName will be null and the file is *not*
   629          * subject to annotation processing.
   700          * subject to annotation processing.
   638                 generatedSourceFileObjects.add(javaFileObject);
   709                 generatedSourceFileObjects.add(javaFileObject);
   639                 openTypeNames.remove(typeName);
   710                 openTypeNames.remove(typeName);
   640                 break;
   711                 break;
   641 
   712 
   642             case CLASS:
   713             case CLASS:
   643                 generatedClasses.put(typeName, javaFileObject);
   714                 generatedClasses.computeIfAbsent(mod, m -> Collections.synchronizedMap(new LinkedHashMap<>())).put(typeName, javaFileObject);
   644                 openTypeNames.remove(typeName);
   715                 openTypeNames.remove(typeName);
   645                 break;
   716                 break;
   646 
   717 
   647             default:
   718             default:
   648                 break;
   719                 break;