Bug 539774 - Spurious compilation failures caused by java model usage
during annotation processing.

Change-Id: If2e649786f4e6d1117636cb52556d8a3f791ec87
diff --git a/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeFilerImpl.java b/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeFilerImpl.java
index 80218d6..75c7633 100644
--- a/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeFilerImpl.java
+++ b/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeFilerImpl.java
@@ -38,12 +38,14 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jdt.apt.core.internal.AptCompilationParticipant;
 import org.eclipse.jdt.apt.core.internal.generatedfile.GeneratedSourceFolderManager;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.apt.pluggable.core.Apt6Plugin;
 import org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeAnnotationProcessorManager;
 import org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeProcessingEnvImpl;
+import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
 
 /**
  * Implementation of the Filer interface that is used in IDE mode.
@@ -162,14 +164,16 @@
 		if (AptCompilationParticipant.getInstance().getJava6GeneratedFiles().contains(file)) {
 			throw new FilerException("Source file already created: " + file.getFullPath()); //$NON-NLS-1$
 		}
-		IJavaProject javaProject = _env.getJavaProject();
-		IType type = null;
-		try {
-			name = name.toString().replace('/', '.');
-			type = javaProject.findType(name.toString());
-		} catch (JavaModelException e) {
-		}
-		if (type != null) {
+		// TODO: is the following correct?
+		// JDK 9's createSourceFile API mentions '/' as separator for a module prefix. 
+		// Otherwise shouldn't <code>name</code> already be "."-separated?
+		name = name.toString().replace('/', '.');
+		
+		ModuleBinding m = _env._current_module;
+		if (m == null)
+			m = _env.getCompiler().lookupEnvironment.UnNamedModule;
+		ReferenceBinding type = m.environment.getType(CharOperation.splitOn('.', name.toString().toCharArray()), m);
+		if (type != null && (type.tagBits & TagBits.HasMissingType) == 0) {
 			throw new FilerException("Source file already exists : " + name); //$NON-NLS-1$
 		}
 		Set<IFile> parentFiles = Collections.emptySet();
diff --git a/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/FilerTests.java b/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/FilerTests.java
index 3d68183..2e3fdc9 100644
--- a/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/FilerTests.java
+++ b/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/FilerTests.java
@@ -17,6 +17,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.InputStream;
+import java.util.Arrays;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IFolder;
@@ -370,7 +371,7 @@
 		env.addClass(projPath.append("src"), "p", "Trigger",
 				"package p;\n" +
 				"import org.eclipse.jdt.apt.pluggable.tests.annotations.FilerTestTrigger;\n" +
-				"@FilerTestTrigger(test = \"testBug534979\", arg0 = \"t\", arg1 = \"Test\")" +
+				"@FilerTestTrigger(test = \"testBug534979\", arg0 = \"p\", arg1 = \"Trigger\")" +
 				"public class Trigger {\n" +
 				"}"
 		); 
@@ -379,6 +380,79 @@
 		fullBuild();
 		assertEquals("Processor reported errors", "FilerException invoking test method testBug534979 - see console for details", ProcessorTestStatus.getErrors());
 	}
+
+	public void testCollisionInOtherModule() throws Throwable {
+		if (!canRunJava9()) {
+			return;
+		}
+		ProcessorTestStatus.reset();
+		IJavaProject jproj = createJava9Project(_projectName);
+		disableJava5Factories(jproj);
+		IProject proj = jproj.getProject();
+		IPath projPath = proj.getFullPath();
+
+		IPath root = projPath.append("src");
+		env.addClass(root, null, "module-info", "module example {requires annotations;}");
+		env.addClass(root, "p", "Trigger",
+				"package p;\n" +
+				"import org.eclipse.jdt.apt.pluggable.tests.annotations.FilerTestTrigger;\n" +
+				"@FilerTestTrigger(test = \"testBug534979\", arg0 = \"java.util\", arg1 = \"HashMap\")" +
+				"public class Trigger {\n" +
+				"}"
+		); 
+
+		AptConfig.setEnabled(jproj, true);
+		fullBuild();
+		assertEquals("Processor reported errors", "FilerException invoking test method testBug534979 - see console for details", ProcessorTestStatus.getErrors());
+	}
+	public void testCollisionWithClassThatTriggers() throws Throwable {
+		if (!canRunJava9()) {
+			return;
+		}
+		ProcessorTestStatus.reset();
+		IJavaProject jproj = createJava9Project(_projectName);
+		disableJava5Factories(jproj);
+		IProject proj = jproj.getProject();
+		IPath projPath = proj.getFullPath();
+
+		IPath root = projPath.append("src");
+		env.addClass(root, null, "module-info", "module example {requires annotations;}");
+		env.addClass(root, "p", "Trigger",
+				"package p;\n" +
+				"import org.eclipse.jdt.apt.pluggable.tests.annotations.FilerTestTrigger;\n" +
+				"@FilerTestTrigger(test = \"testBug534979\", arg0 = \"p\", arg1 = \"Trigger\")" +
+				"public class Trigger {\n" +
+				"}"
+		); 
+
+		AptConfig.setEnabled(jproj, true);
+		fullBuild();
+		assertEquals("Processor reported errors", "FilerException invoking test method testBug534979 - see console for details", ProcessorTestStatus.getErrors());
+	}
+	public void testNoCollisionInSameModule() throws Throwable {
+		if (!canRunJava9()) {
+			return;
+		}
+		ProcessorTestStatus.reset();
+		IJavaProject jproj = createJava9Project(_projectName);
+		disableJava5Factories(jproj);
+		IProject proj = jproj.getProject();
+		IPath projPath = proj.getFullPath();
+
+		IPath root = projPath.append("src");
+		env.addClass(root, null, "module-info", "module example {requires annotations;}");
+		env.addClass(root, "p", "Trigger",
+				"package p;\n" +
+				"import org.eclipse.jdt.apt.pluggable.tests.annotations.FilerTestTrigger;\n" +
+				"@FilerTestTrigger(test = \"testBug534979\", arg0 = \"p\", arg1 = \"Other\")" +
+				"public class Trigger {\n" +
+				"}"
+		); 
+
+		AptConfig.setEnabled(jproj, true);
+		fullBuild();
+		assertEquals("Processor reported errors", ProcessorTestStatus.NO_ERRORS, ProcessorTestStatus.getErrors());
+	}
 	public void testCreateClass1() throws Exception {
 		FilerTesterProc.roundNo = 0;
 		ProcessorTestStatus.reset();
diff --git a/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/processors/filertester/FilerTesterProc.java b/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/processors/filertester/FilerTesterProc.java
index 0d8ce0d..106d252 100644
--- a/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/processors/filertester/FilerTesterProc.java
+++ b/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/processors/filertester/FilerTesterProc.java
@@ -240,11 +240,23 @@
 	}
 	
 	public void testBug534979(Element e, String pkg, String relName) throws Exception {
-		JavaFileObject jfo = _filer.createSourceFile(e.getEnclosingElement().getSimpleName() + "/" + e.getSimpleName());
+		JavaFileObject jfo = _filer.createSourceFile(pkg + "." + relName);
 		PrintWriter pw = null;
 		try {
 			pw = new PrintWriter(jfo.openWriter());
-			pw.println("package " + pkg + ";\npublic class " + e.getSimpleName() + "{ }");
+			pw.println("package " + pkg + ";\npublic class " + relName + "{ }");
+		}
+		finally {
+			if (pw != null)
+				pw.close();
+		}
+	}
+	public void testBug534979InModule(Element e, String pkg, String relName) throws Exception {
+		JavaFileObject jfo = _filer.createSourceFile(pkg+"."+relName, e.getEnclosingElement());
+		PrintWriter pw = null;
+		try {
+			pw = new PrintWriter(jfo.openWriter());
+			pw.println("package " + pkg + ";\npublic class " + relName + "{ }");
 		}
 		finally {
 			if (pw != null)
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java
index efba848..67fc9a8 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java
@@ -23,6 +23,7 @@
 import org.eclipse.jdt.internal.compiler.Compiler;
 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 
 /**
@@ -148,6 +149,17 @@
 	 */
 	@Override
 	public void processAnnotations(CompilationUnitDeclaration[] units, ReferenceBinding[] referenceBindings, boolean isLastRound) {
+		if (units != null) {
+			for (CompilationUnitDeclaration declaration : units) {
+				if (declaration != null && declaration.scope != null) {
+					ModuleBinding m = declaration.scope.module();
+					if (m != null) {
+						_processingEnv._current_module = m;
+						break;
+					}
+				}
+			}
+		}
 		RoundEnvImpl roundEnv = new RoundEnvImpl(units, referenceBindings, isLastRound, _processingEnv);
 		if (_isFirstRound) {
 			_isFirstRound = false;
@@ -161,5 +173,4 @@
 				this, roundEnv, roundEnv.getRootAnnotations(), traceProcessorInfo, traceRounds);
 		dispatcher.round();
 	}
-
 }
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseProcessingEnvImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseProcessingEnvImpl.java
index 071236c..f288a44 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseProcessingEnvImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseProcessingEnvImpl.java
@@ -33,6 +33,7 @@
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 
 /**
@@ -54,6 +55,7 @@
 	private List<ICompilationUnit> _deletedUnits;
 	private boolean _errorRaised;
 	private Factory _factory;
+	public ModuleBinding _current_module;
 
 	public BaseProcessingEnvImpl() {
 		_addedUnits = new ArrayList<>();