langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java Wed Jan 25 10:43:41 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java Thu Jan 26 14:11:38 2017 +0100
@@ -51,9 +51,11 @@
import static javax.tools.StandardLocation.CLASS_OUTPUT;
import com.sun.tools.javac.code.Lint;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.comp.Modules;
+import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.DefinedBy.Api;
@@ -321,6 +323,7 @@
}
JavaFileManager fileManager;
+ JavacElements elementUtils;
Log log;
Modules modules;
Names names;
@@ -331,6 +334,12 @@
private final boolean lint;
/**
+ * Initial inputs passed to the tool. This set must be
+ * synchronized.
+ */
+ private final Set<FileObject> initialInputs;
+
+ /**
* Logical names of all created files. This set must be
* synchronized.
*/
@@ -373,26 +382,30 @@
*/
private final Set<Pair<ModuleSymbol, String>> aggregateGeneratedClassNames;
+ private final Set<String> initialClassNames;
JavacFiler(Context context) {
this.context = context;
fileManager = context.get(JavaFileManager.class);
+ elementUtils = JavacElements.instance(context);
log = Log.instance(context);
modules = Modules.instance(context);
names = Names.instance(context);
syms = Symtab.instance(context);
- fileObjectHistory = synchronizedSet(new LinkedHashSet<FileObject>());
- generatedSourceNames = synchronizedSet(new LinkedHashSet<String>());
- generatedSourceFileObjects = synchronizedSet(new LinkedHashSet<JavaFileObject>());
+ initialInputs = synchronizedSet(new LinkedHashSet<>());
+ fileObjectHistory = synchronizedSet(new LinkedHashSet<>());
+ generatedSourceNames = synchronizedSet(new LinkedHashSet<>());
+ generatedSourceFileObjects = synchronizedSet(new LinkedHashSet<>());
generatedClasses = synchronizedMap(new LinkedHashMap<>());
- openTypeNames = synchronizedSet(new LinkedHashSet<String>());
+ openTypeNames = synchronizedSet(new LinkedHashSet<>());
aggregateGeneratedSourceNames = new LinkedHashSet<>();
aggregateGeneratedClassNames = new LinkedHashSet<>();
+ initialClassNames = new LinkedHashSet<>();
lint = (Lint.instance(context)).isEnabled(PROCESSING);
}
@@ -596,8 +609,13 @@
// TODO: Check if type already exists on source or class path?
// If so, use warning message key proc.type.already.exists
checkName(typename, allowUnnamedPackageInfo);
- if (aggregateGeneratedSourceNames.contains(Pair.of(mod, typename)) ||
- aggregateGeneratedClassNames.contains(Pair.of(mod, typename))) {
+ ClassSymbol existing;
+ boolean alreadySeen = aggregateGeneratedSourceNames.contains(Pair.of(mod, typename)) ||
+ aggregateGeneratedClassNames.contains(Pair.of(mod, typename)) ||
+ initialClassNames.contains(typename) ||
+ ((existing = elementUtils.getTypeElement(typename)) != null &&
+ initialInputs.contains(existing.sourcefile));
+ if (alreadySeen) {
if (lint)
log.warning("proc.type.recreate", typename);
throw new FilerException("Attempt to recreate a file for type " + typename);
@@ -611,16 +629,48 @@
* Check to see if the file has already been opened; if so, throw
* an exception, otherwise add it to the set of files.
*/
- private void checkFileReopening(FileObject fileObject, boolean addToHistory) throws FilerException {
+ private void checkFileReopening(FileObject fileObject, boolean forWriting) throws FilerException {
+ if (isInFileObjectHistory(fileObject, forWriting)) {
+ if (lint)
+ log.warning("proc.file.reopening", fileObject.getName());
+ throw new FilerException("Attempt to reopen a file for path " + fileObject.getName());
+ }
+ if (forWriting)
+ fileObjectHistory.add(fileObject);
+ }
+
+ private boolean isInFileObjectHistory(FileObject fileObject, boolean forWriting) {
+ if (forWriting) {
+ for(FileObject veteran : initialInputs) {
+ try {
+ if (fileManager.isSameFile(veteran, fileObject)) {
+ return true;
+ }
+ } catch (IllegalArgumentException e) {
+ //ignore...
+ }
+ }
+ for (String className : initialClassNames) {
+ try {
+ ClassSymbol existing = elementUtils.getTypeElement(className);
+ if ( existing != null
+ && ( (existing.sourcefile != null && fileManager.isSameFile(existing.sourcefile, fileObject))
+ || (existing.classfile != null && fileManager.isSameFile(existing.classfile, fileObject)))) {
+ return true;
+ }
+ } catch (IllegalArgumentException e) {
+ //ignore...
+ }
+ }
+ }
+
for(FileObject veteran : fileObjectHistory) {
if (fileManager.isSameFile(veteran, fileObject)) {
- if (lint)
- log.warning("proc.file.reopening", fileObject.getName());
- throw new FilerException("Attempt to reopen a file for path " + fileObject.getName());
+ return true;
}
}
- if (addToHistory)
- fileObjectHistory.add(fileObject);
+
+ return false;
}
public boolean newFiles() {
@@ -656,9 +706,17 @@
this.lastRound = lastRound;
}
+ public void setInitialState(Collection<? extends JavaFileObject> initialInputs,
+ Collection<String> initialClassNames) {
+ this.initialInputs.addAll(initialInputs);
+ this.initialClassNames.addAll(initialClassNames);
+ }
+
public void close() {
clearRoundState();
// Cross-round state
+ initialClassNames.clear();
+ initialInputs.clear();
fileObjectHistory.clear();
openTypeNames.clear();
aggregateGeneratedSourceNames.clear();