Bug 534979 - [11] Add warning in annotation processing on redefining
symbols
Change-Id: I3054799f2c9f185a5e84b6ae53b7197568a1cf27
Signed-off-by: jay <jarthana@in.ibm.com>
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 309fd86..e45abeb 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
@@ -22,9 +22,9 @@
import javax.annotation.processing.FilerException;
import javax.lang.model.element.Element;
import javax.tools.FileObject;
+import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
-import javax.tools.JavaFileManager.Location;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
@@ -34,6 +34,8 @@
import org.eclipse.core.runtime.IStatus;
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.internal.apt.pluggable.core.Apt6Plugin;
import org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeAnnotationProcessorManager;
@@ -128,7 +130,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) {
+ throw new FilerException("Source file already exists : " + name); //$NON-NLS-1$
+ }
Set<IFile> parentFiles = Collections.emptySet();
if (originatingElements != null && originatingElements.length > 0) {
parentFiles = new HashSet<IFile>(originatingElements.length);
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 3834cef..b354f74 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
@@ -355,5 +355,23 @@
assertTrue("Processor did not run", ProcessorTestStatus.processorRan());
assertEquals("Processor reported errors", ProcessorTestStatus.NO_ERRORS, ProcessorTestStatus.getErrors());
}
+ public void testBug534979() throws Throwable {
+ ProcessorTestStatus.reset();
+ IJavaProject jproj = createJavaProject(_projectName);
+ disableJava5Factories(jproj);
+ IProject proj = jproj.getProject();
+ IPath projPath = proj.getFullPath();
+ 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\")" +
+ "public class Trigger {\n" +
+ "}"
+ );
+
+ AptConfig.setEnabled(jproj, true);
+ fullBuild();
+ assertEquals("Processor reported errors", "FilerException invoking test method testBug534979 - see console for details", ProcessorTestStatus.getErrors());
+ }
}
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 9736c94..d0164ad 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
@@ -230,7 +230,20 @@
FileObject foGenSrc = _filer.createSourceFile("g.G", e);
checkGenUri(foGenSrc, "G", javaStr, "generated source file");
}
-
+
+ public void testBug534979(Element e, String pkg, String relName) throws Exception {
+ JavaFileObject jfo = _filer.createSourceFile(e.getEnclosingElement().getSimpleName() + "/" + e.getSimpleName());
+ PrintWriter pw = null;
+ try {
+ pw = new PrintWriter(jfo.openWriter());
+ pw.println("package " + pkg + ";\npublic class " + e.getSimpleName() + "{ }");
+ }
+ finally {
+ if (pw != null)
+ pw.close();
+ }
+ }
+
private void checkGenUri(FileObject fo, String name, String content, String category) throws Exception {
PrintWriter pw = null;
try {
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
index bf811a9..6a62c6f 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor b/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor
index 839d9ea..8b8bccf 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor
+++ b/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor
@@ -1,2 +1,3 @@
org.eclipse.jdt.compiler.apt.tests.processors.elements.Java8ElementProcessor
-org.eclipse.jdt.compiler.apt.tests.processors.elements.Java9ElementProcessor
\ No newline at end of file
+org.eclipse.jdt.compiler.apt.tests.processors.elements.Java9ElementProcessor
+org.eclipse.jdt.compiler.apt.tests.processors.elements.Java11ElementProcessor
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java11ElementProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java11ElementProcessor.java
new file mode 100644
index 0000000..706027e
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java11ElementProcessor.java
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.compiler.apt.tests.processors.elements;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaFileObject;
+
+import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor;
+
+/**
+ * A processor that explores the java 9 specific elements and validates the lambda and
+ * type annotated elements. To enable this processor, add
+ * -Aorg.eclipse.jdt.compiler.apt.tests.processors.elements.Java11ElementProcessor to the command line.
+ * @since 3.14
+ */
+@SupportedAnnotationTypes("*")
+public class Java11ElementProcessor extends BaseProcessor {
+ boolean reportSuccessAlready = true;
+ RoundEnvironment roundEnv = null;
+ Messager _messager = null;
+ Filer _filer = null;
+ @Override
+ public synchronized void init(ProcessingEnvironment processingEnv) {
+ super.init(processingEnv);
+ _elementUtils = processingEnv.getElementUtils();
+ _messager = processingEnv.getMessager();
+ _filer = processingEnv.getFiler();
+ }
+ // Always return false from this processor, because it supports "*".
+ // The return value does not signify success or failure!
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ if (roundEnv.processingOver()) {
+ return false;
+ }
+
+ this.roundEnv = roundEnv;
+ Map<String, String> options = processingEnv.getOptions();
+ if (!options.containsKey(this.getClass().getName())) {
+ // Disable this processor unless we are intentionally performing the test.
+ return false;
+ } else {
+ try {
+ if (!invokeTestMethods(options)) {
+ testAll();
+ }
+ if (this.reportSuccessAlready) {
+ super.reportSuccess();
+ }
+ } catch (AssertionFailedError e) {
+ super.reportError(getExceptionStackTrace(e));
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ return false;
+ }
+
+ private boolean invokeTestMethods(Map<String, String> options) throws Throwable {
+ Method testMethod = null;
+ Set<String> keys = options.keySet();
+ boolean testsFound = false;
+ for (String option : keys) {
+ if (option.startsWith("test")) {
+ try {
+ testMethod = this.getClass().getDeclaredMethod(option, new Class[0]);
+ if (testMethod != null) {
+ testsFound = true;
+ testMethod.invoke(this, new Object[0]);
+ }
+ } catch (InvocationTargetException e) {
+ throw e.getCause();
+ } catch (Exception e) {
+ super.reportError(getExceptionStackTrace(e));
+ }
+ }
+ }
+ return testsFound;
+ }
+
+ public void testAll() throws AssertionFailedError {
+ }
+
+ public void testFiler1() throws IOException {
+ String typeName = "abc.internal.TypeInAModule";
+ TypeElement typeElement = _elementUtils.getTypeElement(typeName);
+ assertNotNull("type element should not be null", typeElement);
+ Object obj = null;
+ try {
+ obj = _filer.createSourceFile("mod.a/" + typeName);
+ obj = typeName;
+ } catch (IOException e) {
+ }
+ assertNull("Source should not be created", obj);
+ }
+ public void testFiler2() throws IOException {
+ String typeName = "abc.internal.TypeInAModule";
+ TypeElement typeElement = _elementUtils.getTypeElement(typeName);
+ assertNotNull("type element should not be null", typeElement);
+ Object obj = null;
+ try {
+ obj = _filer.createSourceFile(typeName);
+ obj = typeName;
+ } catch (IOException e) {
+ }
+ assertNull("Source should not be created", obj);
+ }
+ public void testFiler3() throws IOException {
+ String typeName = "mod.a/abc.internal.AnotherTypeInAModule";
+ JavaFileObject obj = null;
+ try {
+ obj = _filer.createSourceFile(typeName);
+ } catch (IOException e) {
+ }
+ assertNotNull("Source should have been created", obj);
+ String name = obj.getName();
+ if (!name.contains("mod.a")) {
+ reportError("source should be created inside the module");
+ }
+
+ }
+ @Override
+ public void reportError(String msg) {
+ throw new AssertionFailedError(msg);
+ }
+ private String getExceptionStackTrace(Throwable t) {
+ StringBuffer buf = new StringBuffer(t.getMessage());
+ StackTraceElement[] traces = t.getStackTrace();
+ for (int i = 0; i < traces.length; i++) {
+ StackTraceElement trace = traces[i];
+ buf.append("\n\tat " + trace);
+ if (i == 12)
+ break; // Don't dump all stacks
+ }
+ return buf.toString();
+ }
+ public void assertModifiers(Set<Modifier> modifiers, String[] expected) {
+ assertEquals("Incorrect no of modifiers", modifiers.size(), expected.length);
+ Set<String> actual = new HashSet<String>(expected.length);
+ for (Modifier modifier : modifiers) {
+ actual.add(modifier.toString());
+ }
+ for(int i = 0, length = expected.length; i < length; i++) {
+ boolean result = actual.remove(expected[i]);
+ if (!result) reportError("Modifier not present :" + expected[i]);
+ }
+ if (!actual.isEmpty()) {
+ reportError("Unexpected modifiers present:" + actual.toString());
+ }
+ }
+ public void assertTrue(String msg, boolean value) {
+ if (!value) reportError(msg);
+ }
+ public void assertFalse(String msg, boolean value) {
+ if (value) reportError(msg);
+ }
+ public void assertSame(String msg, Object obj1, Object obj2) {
+ if (obj1 != obj2) {
+ reportError(msg + ", should be " + obj1.toString() + " but " + obj2.toString());
+ }
+ }
+ public void assertNotSame(String msg, Object obj1, Object obj2) {
+ if (obj1 == obj2) {
+ reportError(msg + ", " + obj1.toString() + " should not be same as " + obj2.toString());
+ }
+ }
+ public void assertNotNull(String msg, Object obj) {
+ if (obj == null) {
+ reportError(msg);
+ }
+ }
+ public void assertNull(String msg, Object obj) {
+ if (obj != null) {
+ reportError(msg);
+ }
+ }
+ public void assertEquals(String message, Object expected, Object actual) {
+ if (equalsRegardingNull(expected, actual)) {
+ return;
+ } else {
+ reportError(message + ", expected " + expected.toString() + " but was " + actual.toString());
+ }
+ }
+
+ public void assertEquals(String message, Object expected, Object alternateExpected, Object actual) {
+ if (equalsRegardingNull(expected, actual) || equalsRegardingNull(alternateExpected, actual)) {
+ return;
+ } else {
+ reportError(message + ", expected " + expected.toString() + " but was " + actual.toString());
+ }
+ }
+
+ static boolean equalsRegardingNull(Object expected, Object actual) {
+ if (expected == null) {
+ return actual == null;
+ }
+ return expected.equals(actual);
+ }
+
+ public void assertEquals(String msg, int expected, int actual) {
+ if (expected != actual) {
+ StringBuffer buf = new StringBuffer();
+ buf.append(msg);
+ buf.append(", expected " + expected + " but was " + actual);
+ reportError(buf.toString());
+ }
+ }
+ public void assertEquals(Object expected, Object actual) {
+ if (expected != actual) {
+
+ }
+ }
+ private class AssertionFailedError extends Error {
+ private static final long serialVersionUID = 1L;
+
+ public AssertionFailedError(String msg) {
+ super(msg);
+ }
+ }
+}
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java9ElementProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java9ElementProcessor.java
index 8310874..dbf6e82 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java9ElementProcessor.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java9ElementProcessor.java
@@ -25,6 +25,7 @@
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.AnnotatedConstruct;
+import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
@@ -58,11 +59,26 @@
boolean reportSuccessAlready = true;
RoundEnvironment roundEnv = null;
Messager _messager = null;
+ boolean isJre11;
+ boolean isJre10;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
_typeUtils = processingEnv.getTypeUtils();
_messager = processingEnv.getMessager();
+ try {
+ SourceVersion.valueOf("RELEASE_11");
+ this.isJre10 = true;
+ this.isJre11 = true;
+ } catch(IllegalArgumentException iae) {
+ }
+ if (!this.isJre11) {
+ try {
+ SourceVersion.valueOf("RELEASE_10");
+ this.isJre10 = true;
+ } catch(IllegalArgumentException iae) {
+ }
+ }
}
// Always return false from this processor, because it supports "*".
// The return value does not signify success or failure!
@@ -391,7 +407,7 @@
assertNotNull("java.base module null", base);
List<? extends Directive> directives = base.getDirectives();
List<Directive> filterDirective = filterDirective(directives, DirectiveKind.EXPORTS);
- assertEquals("incorrect no of exports", 108 , filterDirective.size());
+ assertEquals("incorrect no of exports", this.isJre11 ? 108 : (this.isJre10 ? 102 : 108) , filterDirective.size());
ExportsDirective pack = null;
for (Directive directive : filterDirective) {
ModuleElement.ExportsDirective exports = (ExportsDirective) directive;
@@ -506,7 +522,7 @@
assertNotNull("java.sql module null", base);
List<? extends Directive> directives = base.getDirectives();
List<Directive> filterDirective = filterDirective(directives, DirectiveKind.REQUIRES);
- assertEquals("Incorrect no of requires", 3, filterDirective.size());
+ assertEquals("Incorrect no of requires", this.isJre11 ? 4 : 3, filterDirective.size());
RequiresDirective req = null;
for (Directive directive : filterDirective) {
if (((RequiresDirective) directive).getDependency().getQualifiedName().toString().equals("java.logging")) {
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java
index 7903d88..a59ae63 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java
@@ -120,6 +120,10 @@
public static void compileInModuleMode(JavaCompiler compiler, List<String> options, String processor,
File targetFolder, DiagnosticListener<? super JavaFileObject> listener, boolean multiModule) {
+ compileInModuleMode(compiler, options, processor, targetFolder, listener, multiModule, true);
+ }
+ public static void compileInModuleMode(JavaCompiler compiler, List<String> options, String processor,
+ File targetFolder, DiagnosticListener<? super JavaFileObject> listener, boolean multiModule, boolean processBinariesAgain) {
StandardJavaFileManager manager = compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset());
Iterable<? extends File> location = manager.getLocation(StandardLocation.CLASS_PATH);
// create new list containing inputfile
@@ -148,6 +152,9 @@
System.err.println("Compilation failed: " + errorOutput);
junit.framework.TestCase.assertTrue("Compilation failed : " + errorOutput, false);
}
+ if (!processBinariesAgain) {
+ return;
+ }
List<String> classes = new ArrayList<>();
try {
manager = compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset());
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java11ElementsTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java11ElementsTests.java
new file mode 100644
index 0000000..0565b82
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java11ElementsTests.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2018 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.compiler.apt.tests;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.lang.model.SourceVersion;
+import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
+
+import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
+
+import junit.framework.TestCase;
+
+public class Java11ElementsTests extends TestCase {
+ private static final String MODULE_PROC = "org.eclipse.jdt.compiler.apt.tests.processors.elements.Java11ElementProcessor";
+
+ public void testFiler1() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testFiler1", null);
+ }
+ public void testFiler1Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ internalTest2(compiler, MODULE_PROC, "testFiler1", null);
+ }
+ public void testFiler2() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testFiler2", null);
+ }
+ public void testFiler2Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ internalTest2(compiler, MODULE_PROC, "testFiler2", null);
+ }
+ public void testFiler3() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testFiler3", null);
+ }
+ public void testFiler3Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ internalTest2(compiler, MODULE_PROC, "testFiler3", null);
+ }
+ protected void internalTestWithBinary(JavaCompiler compiler, String processor, String compliance, String testMethod, String testClass, String resourceArea) throws IOException {
+ if (!canRunJava11()) {
+ return;
+ }
+ System.clearProperty(processor);
+ File targetFolder = TestUtils.concatPath(BatchTestUtils.getSrcFolderName(), "targets", resourceArea);
+ if (testClass == null || testClass.equals("")) {
+ BatchTestUtils.copyResources("targets/" + resourceArea, targetFolder);
+ } else {
+ BatchTestUtils.copyResource("targets/" + resourceArea + "/" + testClass, targetFolder);
+ }
+
+
+ List<String> options = new ArrayList<String>();
+ options.add("-A" + processor);
+ options.add("-A" + testMethod);
+ options.add("-processor");
+ options.add(processor);
+ // Javac 1.8 doesn't (yet?) support the -1.8 option
+ if (compiler instanceof EclipseCompiler) {
+ options.add("-" + compliance);
+ } else {
+ options.add("-source");
+ options.add(compliance);
+ }
+ BatchTestUtils.compileTreeAndProcessBinaries(compiler, options, processor, targetFolder, null);
+
+ // If it succeeded, the processor will have set this property to "succeeded";
+ // if not, it will set it to an error value.
+ assertEquals("succeeded", System.getProperty(processor));
+ }
+ /*
+ * Tests are run in multi-module mode
+ */
+ private void internalTest2(JavaCompiler compiler, String processor, String testMethod, String testClass) throws IOException {
+ if (!canRunJava11()) {
+ return;
+ }
+ System.clearProperty(MODULE_PROC);
+ File srcRoot = TestUtils.concatPath(BatchTestUtils.getSrcFolderName());
+ BatchTestUtils.copyResources("mod_locations/modules", srcRoot);
+
+ List<String> options = new ArrayList<String>();
+ options.add("-processor");
+ options.add(MODULE_PROC);
+ options.add("-A" + MODULE_PROC);
+ options.add("-A" + testMethod);
+ if (compiler instanceof EclipseCompiler) {
+ options.add("-9");
+ }
+ BatchTestUtils.compileInModuleMode(compiler, options, MODULE_PROC, srcRoot, null, true, false);
+ assertEquals("succeeded", System.getProperty(MODULE_PROC));
+ }
+ public boolean canRunJava11() {
+ try {
+ SourceVersion.valueOf("RELEASE_11");
+ } catch(IllegalArgumentException iae) {
+ return false;
+ }
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ BatchTestUtils.init();
+ }
+
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#tearDown()
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java
index 31a29ea..d5d522d 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2015 BEA Systems, Inc.
+ * Copyright (c) 2006, 2018 BEA Systems, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -21,6 +21,7 @@
import javax.annotation.processing.Filer;
import javax.annotation.processing.FilerException;
import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
import javax.tools.FileObject;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
@@ -133,8 +134,19 @@
@Override
public JavaFileObject createSourceFile(CharSequence name,
Element... originatingElements) throws IOException {
- JavaFileObject jfo = _fileManager.getJavaFileForOutput(
- StandardLocation.SOURCE_OUTPUT, name.toString(), JavaFileObject.Kind.SOURCE, null);
+ String moduleAndPkgString = name.toString();
+ int slash = moduleAndPkgString.indexOf('/');
+ String mod = null;
+ if (slash != -1) {
+ name = moduleAndPkgString.substring(slash + 1, name.length());
+ mod = moduleAndPkgString.substring(0, slash);
+ }
+ TypeElement typeElement = _env._elementUtils.getTypeElement(name);
+ if (typeElement != null) {
+ throw new FilerException("Source file already exists : " + moduleAndPkgString); //$NON-NLS-1$
+ }
+ Location location = mod == null ? StandardLocation.SOURCE_OUTPUT : _fileManager.getLocationForModule(StandardLocation.SOURCE_OUTPUT, mod);
+ JavaFileObject jfo = _fileManager.getJavaFileForOutput(location, name.toString(), JavaFileObject.Kind.SOURCE, null);
URI uri = jfo.toUri();
if (_createdFiles.contains(uri)) {
throw new FilerException("Source file already created : " + name); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java
index f6a71b1..b12f1d7 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2017 IBM Corporation and others.
+ * Copyright (c) 2006, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -1390,7 +1390,17 @@
@Override
public Location getLocationForModule(Location location, String moduleName) throws IOException {
validateModuleLocation(location, moduleName);
- return this.locationHandler.getLocation(location, moduleName);
+ Location result = this.locationHandler.getLocation(location, moduleName);
+ if (result == null && location == StandardLocation.CLASS_OUTPUT) {
+ LocationWrapper wrapper = this.locationHandler.getLocation(StandardLocation.MODULE_SOURCE_PATH, moduleName);
+ deriveOutputLocationForModules(moduleName, wrapper.paths);
+ result = getLocationForModule(location, moduleName);
+ } else if (result == null && location == StandardLocation.SOURCE_OUTPUT) {
+ LocationWrapper wrapper = this.locationHandler.getLocation(StandardLocation.MODULE_SOURCE_PATH, moduleName);
+ deriveSourceOutputLocationForModules(moduleName, wrapper.paths);
+ result = getLocationForModule(location, moduleName);
+ }
+ return result;
}
@Override
@@ -1448,7 +1458,50 @@
}
return null;
}
-
+ private void deriveOutputLocationForModules(String moduleName, Collection<? extends Path> paths) {
+ LocationWrapper wrapper = this.locationHandler.getLocation(StandardLocation.CLASS_OUTPUT, moduleName);
+ if (wrapper == null) {
+ // First get from our internally known location for legacy/unnamed location
+ wrapper = this.locationHandler.getLocation(StandardLocation.CLASS_OUTPUT, ""); //$NON-NLS-1$
+ if (wrapper == null) {
+ wrapper = this.locationHandler.getLocation(StandardLocation.CLASS_OUTPUT);
+ }
+ if (wrapper != null) {
+ Iterator<? extends Path> iterator = wrapper.paths.iterator();
+ if (iterator.hasNext()) {
+ try {
+ // Per module output location is always a singleton list
+ Path path = iterator.next().resolve(moduleName);
+ this.locationHandler.setLocation(StandardLocation.CLASS_OUTPUT, moduleName, Collections.singletonList(path));
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ private void deriveSourceOutputLocationForModules(String moduleName, Collection<? extends Path> paths) {
+ LocationWrapper wrapper = this.locationHandler.getLocation(StandardLocation.SOURCE_OUTPUT, moduleName);
+ if (wrapper == null) {
+ // First get from our internally known location for legacy/unnamed location
+ wrapper = this.locationHandler.getLocation(StandardLocation.SOURCE_OUTPUT, ""); //$NON-NLS-1$
+ if (wrapper == null) {
+ wrapper = this.locationHandler.getLocation(StandardLocation.SOURCE_OUTPUT);
+ }
+ if (wrapper != null) {
+ Iterator<? extends Path> iterator = wrapper.paths.iterator();
+ if (iterator.hasNext()) {
+ try {
+ // Per module output location is always a singleton list
+ Path path = iterator.next().resolve(moduleName);
+ this.locationHandler.setLocation(StandardLocation.SOURCE_OUTPUT, moduleName, Collections.singletonList(path));
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
@Override
public void setLocationForModule(Location location, String moduleName, Collection<? extends Path> paths) throws IOException {
validateModuleLocation(location, moduleName);
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
index 62472da..a5c8c2d 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
@@ -1421,6 +1421,10 @@
LocationWrapper wrapper = this.locationHandler.getLocation(StandardLocation.MODULE_SOURCE_PATH, moduleName);
deriveOutputLocationForModules(moduleName, wrapper.paths);
result = getLocationForModule(location, moduleName);
+ } else if (result == null && location == StandardLocation.SOURCE_OUTPUT) {
+ LocationWrapper wrapper = this.locationHandler.getLocation(StandardLocation.MODULE_SOURCE_PATH, moduleName);
+ deriveSourceOutputLocationForModules(moduleName, wrapper.paths);
+ result = getLocationForModule(location, moduleName);
}
return result;
}
@@ -1502,6 +1506,28 @@
}
}
}
+ private void deriveSourceOutputLocationForModules(String moduleName, Collection<? extends Path> paths) {
+ LocationWrapper wrapper = this.locationHandler.getLocation(StandardLocation.SOURCE_OUTPUT, moduleName);
+ if (wrapper == null) {
+ // First get from our internally known location for legacy/unnamed location
+ wrapper = this.locationHandler.getLocation(StandardLocation.SOURCE_OUTPUT, ""); //$NON-NLS-1$
+ if (wrapper == null) {
+ wrapper = this.locationHandler.getLocation(StandardLocation.SOURCE_OUTPUT);
+ }
+ if (wrapper != null) {
+ Iterator<? extends Path> iterator = wrapper.paths.iterator();
+ if (iterator.hasNext()) {
+ try {
+ // Per module output location is always a singleton list
+ Path path = iterator.next().resolve(moduleName);
+ this.locationHandler.setLocation(StandardLocation.SOURCE_OUTPUT, moduleName, Collections.singletonList(path));
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
@Override
public void setLocationForModule(Location location, String moduleName, Collection<? extends Path> paths) throws IOException {
validateModuleLocation(location, moduleName);