From f668bca61ebe161adbab98cbb94df79497197a1b Mon Sep 17 00:00:00 2001 From: jay Date: Tue, 26 Jun 2018 16:06:52 +0530 Subject: Bug 534979 - [11] Add warning in annotation processing on redefining symbols Change-Id: I3054799f2c9f185a5e84b6ae53b7197568a1cf27 Signed-off-by: jay --- .../lib/apttestprocessors8.jar | Bin 235964 -> 244104 bytes .../services/javax.annotation.processing.Processor | 3 +- .../elements/Java11ElementProcessor.java | 242 +++++++++++++++++++++ .../processors/elements/Java9ElementProcessor.java | 20 +- .../jdt/compiler/apt/tests/BatchTestUtils.java | 7 + .../compiler/apt/tests/Java11ElementsTests.java | 132 +++++++++++ 6 files changed, 401 insertions(+), 3 deletions(-) create mode 100644 org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java11ElementProcessor.java create mode 100644 org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java11ElementsTests.java (limited to 'org.eclipse.jdt.compiler.apt.tests') diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar index bf811a9fe5..6a62c6f733 100644 Binary files a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar and b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar 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 839d9ea2ee..8b8bccf832 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 0000000000..706027e60c --- /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 annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + return false; + } + + this.roundEnv = roundEnv; + Map 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 options) throws Throwable { + Method testMethod = null; + Set 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 modifiers, String[] expected) { + assertEquals("Incorrect no of modifiers", modifiers.size(), expected.length); + Set actual = new HashSet(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 8310874eba..dbf6e824e3 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.ProcessingEnvironment; 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 @@ public class Java9ElementProcessor extends BaseProcessor { 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 @@ public class Java9ElementProcessor extends BaseProcessor { assertNotNull("java.base module null", base); List directives = base.getDirectives(); List 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 @@ public class Java9ElementProcessor extends BaseProcessor { assertNotNull("java.sql module null", base); List directives = base.getDirectives(); List 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 7903d88f26..a59ae63d88 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 class BatchTestUtils { public static void compileInModuleMode(JavaCompiler compiler, List options, String processor, File targetFolder, DiagnosticListener listener, boolean multiModule) { + compileInModuleMode(compiler, options, processor, targetFolder, listener, multiModule, true); + } + public static void compileInModuleMode(JavaCompiler compiler, List options, String processor, + File targetFolder, DiagnosticListener listener, boolean multiModule, boolean processBinariesAgain) { StandardJavaFileManager manager = compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset()); Iterable location = manager.getLocation(StandardLocation.CLASS_PATH); // create new list containing inputfile @@ -148,6 +152,9 @@ public class BatchTestUtils { System.err.println("Compilation failed: " + errorOutput); junit.framework.TestCase.assertTrue("Compilation failed : " + errorOutput, false); } + if (!processBinariesAgain) { + return; + } List 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 0000000000..0565b82f81 --- /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 options = new ArrayList(); + 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 options = new ArrayList(); + 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 -- cgit v1.2.3