langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java
changeset 43368 cabe410a7a5c
parent 42815 050370edaade
child 44291 e1b620ac6c98
equal deleted inserted replaced
43367:7797472a9ed5 43368:cabe410a7a5c
    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.ClassSymbol;
    54 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
    55 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
    55 import com.sun.tools.javac.code.Symtab;
    56 import com.sun.tools.javac.code.Symtab;
    56 import com.sun.tools.javac.comp.Modules;
    57 import com.sun.tools.javac.comp.Modules;
       
    58 import com.sun.tools.javac.model.JavacElements;
    57 import com.sun.tools.javac.util.*;
    59 import com.sun.tools.javac.util.*;
    58 import com.sun.tools.javac.util.DefinedBy.Api;
    60 import com.sun.tools.javac.util.DefinedBy.Api;
    59 
    61 
    60 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
    62 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
    61 
    63 
   319             }
   321             }
   320         }
   322         }
   321     }
   323     }
   322 
   324 
   323     JavaFileManager fileManager;
   325     JavaFileManager fileManager;
       
   326     JavacElements elementUtils;
   324     Log log;
   327     Log log;
   325     Modules modules;
   328     Modules modules;
   326     Names names;
   329     Names names;
   327     Symtab syms;
   330     Symtab syms;
   328     Context context;
   331     Context context;
   329     boolean lastRound;
   332     boolean lastRound;
   330 
   333 
   331     private final boolean lint;
   334     private final boolean lint;
   332 
   335 
   333     /**
   336     /**
       
   337      * Initial inputs passed to the tool.  This set must be
       
   338      * synchronized.
       
   339      */
       
   340     private final Set<FileObject> initialInputs;
       
   341 
       
   342     /**
   334      * Logical names of all created files.  This set must be
   343      * Logical names of all created files.  This set must be
   335      * synchronized.
   344      * synchronized.
   336      */
   345      */
   337     private final Set<FileObject> fileObjectHistory;
   346     private final Set<FileObject> fileObjectHistory;
   338 
   347 
   371      * Names of all created class files.  Its iterators should
   380      * Names of all created class files.  Its iterators should
   372      * preserve insertion order.
   381      * preserve insertion order.
   373      */
   382      */
   374     private final Set<Pair<ModuleSymbol, String>> aggregateGeneratedClassNames;
   383     private final Set<Pair<ModuleSymbol, String>> aggregateGeneratedClassNames;
   375 
   384 
       
   385     private final Set<String> initialClassNames;
   376 
   386 
   377     JavacFiler(Context context) {
   387     JavacFiler(Context context) {
   378         this.context = context;
   388         this.context = context;
   379         fileManager = context.get(JavaFileManager.class);
   389         fileManager = context.get(JavaFileManager.class);
       
   390         elementUtils = JavacElements.instance(context);
   380 
   391 
   381         log = Log.instance(context);
   392         log = Log.instance(context);
   382         modules = Modules.instance(context);
   393         modules = Modules.instance(context);
   383         names = Names.instance(context);
   394         names = Names.instance(context);
   384         syms = Symtab.instance(context);
   395         syms = Symtab.instance(context);
   385 
   396 
   386         fileObjectHistory = synchronizedSet(new LinkedHashSet<FileObject>());
   397         initialInputs = synchronizedSet(new LinkedHashSet<>());
   387         generatedSourceNames = synchronizedSet(new LinkedHashSet<String>());
   398         fileObjectHistory = synchronizedSet(new LinkedHashSet<>());
   388         generatedSourceFileObjects = synchronizedSet(new LinkedHashSet<JavaFileObject>());
   399         generatedSourceNames = synchronizedSet(new LinkedHashSet<>());
       
   400         generatedSourceFileObjects = synchronizedSet(new LinkedHashSet<>());
   389 
   401 
   390         generatedClasses = synchronizedMap(new LinkedHashMap<>());
   402         generatedClasses = synchronizedMap(new LinkedHashMap<>());
   391 
   403 
   392         openTypeNames  = synchronizedSet(new LinkedHashSet<String>());
   404         openTypeNames  = synchronizedSet(new LinkedHashSet<>());
   393 
   405 
   394         aggregateGeneratedSourceNames = new LinkedHashSet<>();
   406         aggregateGeneratedSourceNames = new LinkedHashSet<>();
   395         aggregateGeneratedClassNames  = new LinkedHashSet<>();
   407         aggregateGeneratedClassNames  = new LinkedHashSet<>();
       
   408         initialClassNames  = new LinkedHashSet<>();
   396 
   409 
   397         lint = (Lint.instance(context)).isEnabled(PROCESSING);
   410         lint = (Lint.instance(context)).isEnabled(PROCESSING);
   398     }
   411     }
   399 
   412 
   400     @Override @DefinedBy(Api.ANNOTATION_PROCESSING)
   413     @Override @DefinedBy(Api.ANNOTATION_PROCESSING)
   594 
   607 
   595     private void checkNameAndExistence(ModuleSymbol mod, String typename, boolean allowUnnamedPackageInfo) throws FilerException {
   608     private void checkNameAndExistence(ModuleSymbol mod, String typename, boolean allowUnnamedPackageInfo) throws FilerException {
   596         // TODO: Check if type already exists on source or class path?
   609         // TODO: Check if type already exists on source or class path?
   597         // If so, use warning message key proc.type.already.exists
   610         // If so, use warning message key proc.type.already.exists
   598         checkName(typename, allowUnnamedPackageInfo);
   611         checkName(typename, allowUnnamedPackageInfo);
   599         if (aggregateGeneratedSourceNames.contains(Pair.of(mod, typename)) ||
   612         ClassSymbol existing;
   600             aggregateGeneratedClassNames.contains(Pair.of(mod, typename))) {
   613         boolean alreadySeen = aggregateGeneratedSourceNames.contains(Pair.of(mod, typename)) ||
       
   614                               aggregateGeneratedClassNames.contains(Pair.of(mod, typename)) ||
       
   615                               initialClassNames.contains(typename) ||
       
   616                               ((existing = elementUtils.getTypeElement(typename)) != null &&
       
   617                                initialInputs.contains(existing.sourcefile));
       
   618         if (alreadySeen) {
   601             if (lint)
   619             if (lint)
   602                 log.warning("proc.type.recreate", typename);
   620                 log.warning("proc.type.recreate", typename);
   603             throw new FilerException("Attempt to recreate a file for type " + typename);
   621             throw new FilerException("Attempt to recreate a file for type " + typename);
   604         }
   622         }
   605         if (!mod.isUnnamed() && !typename.contains(".")) {
   623         if (!mod.isUnnamed() && !typename.contains(".")) {
   609 
   627 
   610     /**
   628     /**
   611      * Check to see if the file has already been opened; if so, throw
   629      * Check to see if the file has already been opened; if so, throw
   612      * an exception, otherwise add it to the set of files.
   630      * an exception, otherwise add it to the set of files.
   613      */
   631      */
   614     private void checkFileReopening(FileObject fileObject, boolean addToHistory) throws FilerException {
   632     private void checkFileReopening(FileObject fileObject, boolean forWriting) throws FilerException {
       
   633         if (isInFileObjectHistory(fileObject, forWriting)) {
       
   634             if (lint)
       
   635                 log.warning("proc.file.reopening", fileObject.getName());
       
   636             throw new FilerException("Attempt to reopen a file for path " + fileObject.getName());
       
   637         }
       
   638         if (forWriting)
       
   639             fileObjectHistory.add(fileObject);
       
   640     }
       
   641 
       
   642     private boolean isInFileObjectHistory(FileObject fileObject, boolean forWriting) {
       
   643         if (forWriting) {
       
   644             for(FileObject veteran : initialInputs) {
       
   645                 try {
       
   646                     if (fileManager.isSameFile(veteran, fileObject)) {
       
   647                         return true;
       
   648                     }
       
   649                 } catch (IllegalArgumentException e) {
       
   650                     //ignore...
       
   651                 }
       
   652             }
       
   653             for (String className : initialClassNames) {
       
   654                 try {
       
   655                     ClassSymbol existing = elementUtils.getTypeElement(className);
       
   656                     if (   existing != null
       
   657                         && (   (existing.sourcefile != null && fileManager.isSameFile(existing.sourcefile, fileObject))
       
   658                             || (existing.classfile != null && fileManager.isSameFile(existing.classfile, fileObject)))) {
       
   659                         return true;
       
   660                     }
       
   661                 } catch (IllegalArgumentException e) {
       
   662                     //ignore...
       
   663                 }
       
   664             }
       
   665         }
       
   666 
   615         for(FileObject veteran : fileObjectHistory) {
   667         for(FileObject veteran : fileObjectHistory) {
   616             if (fileManager.isSameFile(veteran, fileObject)) {
   668             if (fileManager.isSameFile(veteran, fileObject)) {
   617                 if (lint)
   669                 return true;
   618                     log.warning("proc.file.reopening", fileObject.getName());
   670             }
   619                 throw new FilerException("Attempt to reopen a file for path " + fileObject.getName());
   671         }
   620             }
   672 
   621         }
   673         return false;
   622         if (addToHistory)
       
   623             fileObjectHistory.add(fileObject);
       
   624     }
   674     }
   625 
   675 
   626     public boolean newFiles() {
   676     public boolean newFiles() {
   627         return (!generatedSourceNames.isEmpty())
   677         return (!generatedSourceNames.isEmpty())
   628             || (!generatedClasses.isEmpty());
   678             || (!generatedClasses.isEmpty());
   654 
   704 
   655     void setLastRound(boolean lastRound) {
   705     void setLastRound(boolean lastRound) {
   656         this.lastRound = lastRound;
   706         this.lastRound = lastRound;
   657     }
   707     }
   658 
   708 
       
   709     public void setInitialState(Collection<? extends JavaFileObject> initialInputs,
       
   710                                 Collection<String> initialClassNames) {
       
   711         this.initialInputs.addAll(initialInputs);
       
   712         this.initialClassNames.addAll(initialClassNames);
       
   713     }
       
   714 
   659     public void close() {
   715     public void close() {
   660         clearRoundState();
   716         clearRoundState();
   661         // Cross-round state
   717         // Cross-round state
       
   718         initialClassNames.clear();
       
   719         initialInputs.clear();
   662         fileObjectHistory.clear();
   720         fileObjectHistory.clear();
   663         openTypeNames.clear();
   721         openTypeNames.clear();
   664         aggregateGeneratedSourceNames.clear();
   722         aggregateGeneratedSourceNames.clear();
   665         aggregateGeneratedClassNames.clear();
   723         aggregateGeneratedClassNames.clear();
   666     }
   724     }