# HG changeset patch # User jjg # Date 1352336479 28800 # Node ID 2986e7052952960ad46923f435268318f8b084d4 # Parent 19d6ba779759ce139b41901822d73646f94016ed 8002157: Write combo compiler tests for repeating annotations for JDK8 Reviewed-by: darcy, jjg Contributed-by: sonali.goel@oracle.com diff -r 19d6ba779759 -r 2986e7052952 test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java Wed Nov 07 17:01:19 2012 -0800 @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8002157 + * @author sogoel + * @summary Basic Syntax test for repeating annotations on all elements + * @build Helper + * @compile BasicSyntaxCombo.java + * @run main BasicSyntaxCombo + */ + + +import java.util.Arrays; +import javax.tools.DiagnosticCollector; +import javax.tools.JavaFileObject; +import javax.tools.Diagnostic; + +/* + * Generate test src for element kinds with repeating annotations. + * The test uses Helper.java to get the template to create test src and + * compile the test src. + * The test passes if valid test src compile as expected and + * and invalid test src fail as expected. + */ + +public class BasicSyntaxCombo extends Helper{ + static int errors = 0; + static boolean exitMode = false; + static String TESTPKG = "testpkg"; + static String srcContent = ""; + static String pkgInfoContent = ""; + + static { + // If EXIT_ON_FAIL is set, the combo test will exit at the first error + String exitOnFail = System.getenv("EXIT_ON_FAIL"); + if (exitOnFail == null || exitOnFail == "" ) { + exitMode = false; + } + else { + if (exitOnFail.equalsIgnoreCase("YES") || + exitOnFail.equalsIgnoreCase("Y") || + exitOnFail.equalsIgnoreCase("TRUE") || + exitOnFail.equalsIgnoreCase("T")) { + exitMode = true; + } + } + } + + enum TestElem { + ANNOTATION_TYPE(true), + PACKAGE(true), + CONSTRUCTOR(true), + FIELD(true), + LOCAL_VARIABLE(true), + METHOD(true), + TYPE(true), + PARAMETER(true), + INNER_CLASS(true), + STATIC_INI(false), + INSTANCE_INI(false); + + TestElem(boolean compile) { + this.compile = compile; + } + + boolean compile; + boolean shouldCompile() { + return compile; + } + } + + public static void main(String[] args) throws Exception { + new BasicSyntaxCombo().runTest(); + } + + public void runTest() throws Exception { + boolean result = false; + Iterable files = null; + int testCtr = 0; + for (TestElem type : TestElem.values()) { + testCtr++; + String className = "BasicCombo_"+type; + files = getFileList(className, type); + + boolean shouldCompile = type.shouldCompile(); + result = getCompileResult(className, shouldCompile,files); + + if (shouldCompile && !result) { + error(className + " did not compile as expected", srcContent); + if(!pkgInfoContent.isEmpty()) { + System.out.println("package-info.java contents: " + pkgInfoContent); + } + } + + if (!shouldCompile && !result) { + error(className + " compiled unexpectedly", srcContent); + if(!pkgInfoContent.isEmpty()) { + System.out.println("package-info.java contents: " + pkgInfoContent); + } + } + } + + System.out.println("Total number of tests run: " + testCtr); + System.out.println("Total number of errors: " + errors); + + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + private boolean getCompileResult(String className, boolean shouldCompile, + Iterable files) throws Exception { + + DiagnosticCollector diagnostics = + new DiagnosticCollector(); + boolean ok = Helper.compileCode(diagnostics,files); + if (!shouldCompile && !ok) { + checkErrorKeys(className, diagnostics); + } + return (shouldCompile == ok); + } + + private void checkErrorKeys ( + String className, DiagnosticCollector diagnostics) throws Exception { + String expectedErrKey = "compiler.err.illegal.start.of.type"; + for (Diagnostic d : diagnostics.getDiagnostics()) { + if ((d.getKind() == Diagnostic.Kind.ERROR) && + d.getCode().contains(expectedErrKey)) { + break; // Found the expected error + } else { + error("Incorrect error key, expected = " + + expectedErrKey + ", Actual = " + d.getCode() + + " for className = " + className, srcContent); + } + } + } + + private Iterable getFileList(String className, + TestElem type ) { + + String template = Helper.template; + String replaceStr = "/*"+type+"*/"; + StringBuilder annoData = new StringBuilder(); + annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal()) + .append(Helper.ContentVars.CONTAINERFOR.getVal()) + .append(Helper.ContentVars.CONTAINER.getVal()) + .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.BASE.getVal()); + + JavaFileObject pkgInfoFile = null; + + if (type.equals("PACKAGE")) { + srcContent = template.replace(replaceStr, "package testpkg;") + .replace("#ClassName", className); + + String pkgInfoName = TESTPKG+"."+"package-info"; + pkgInfoContent = Helper.ContentVars.REPEATABLEANNO.getVal() + + "package " + TESTPKG + ";" + + annoData; + pkgInfoFile = getFile(pkgInfoName, pkgInfoContent); + } else { + template = template.replace(replaceStr, Helper.ContentVars.REPEATABLEANNO.getVal()) + .replace("#ClassName", className); + srcContent = annoData + template; + } + + JavaFileObject srcFile = getFile(className, srcContent); + + Iterable files = null; + if (pkgInfoFile != null) { + files = Arrays.asList(pkgInfoFile,srcFile); + } + else { + files = Arrays.asList(srcFile); + } + return files; + } + + private void error(String msg, String... contents) throws Exception { + System.out.println("error: " + msg); + errors++; + if (contents.length == 1) { + System.out.println("Contents = " + contents[0]); + } + // Test exits as soon as it gets a failure + if (exitMode) throw new Exception(); + } +} diff -r 19d6ba779759 -r 2986e7052952 test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java Wed Nov 07 17:01:19 2012 -0800 @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8002157 + * @author sogoel + * @summary Combo test to check for usage of Deprecated + * @build Helper + * @compile DeprecatedAnnoCombo.java + * @run main DeprecatedAnnoCombo + */ + +import java.util.List; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.JavaFileObject; + +/* + * Generate test src for use of @Deprecated on base anno + * or container anno or on both. In all cases, test src should compile and a + * warning should be generated. Repeating annotations used only on class for + * these generated test src. + */ + +public class DeprecatedAnnoCombo extends Helper { + static int errors = 0; + + enum TestCases { + DeprecatedonBoth, + DeprecatedonContainer, + DeprecatedonBase; + } + + public static void main(String[] args) throws Exception { + new DeprecatedAnnoCombo().runTest(); + } + + public void runTest() throws Exception { + boolean ok = false; + int testCtr = 0; + + for (TestCases clName : TestCases.values()) { + testCtr++; + + // Create test source content + String contents = getContent(clName.toString()); + + // Compile the generated source file + DiagnosticCollector diagnostics = + new DiagnosticCollector(); + ok = compileCode(clName.toString(), contents, diagnostics); + + String errorKey1 = "compiler.note.deprecated.filename"; + String errorKey2 = "compiler.note.deprecated.recompile"; + List> diags = diagnostics.getDiagnostics(); + + //Check for deprecated warnings + if (ok) { + if (diags.size() == 0) { + error("Did not get any warnings for @Deprecated usage"); + } else { + for (Diagnostic d : diags) { + if (d.getKind() == Diagnostic.Kind.NOTE) { + if (d.getCode().contains(errorKey1) + || d.getCode().contains(errorKey2)) { + System.out.println("TestCase =" + clName + " passed as expected"); + } else { + error("TestCase =" + clName + " did not give correct warnings" + + "Expected warning keys: " + + "errorKey1 = " + errorKey1 + + "errorKey2 = " + errorKey2 + + "actualErrorKey = " + d.getCode(), contents); + } + } else { + error("Diagnostic Kind is incorrect, expected = " + + Diagnostic.Kind.NOTE + "actual = " + d.getKind(), contents); + } + } + } + } else { + error("TestCase =" + clName + " did not compile as expected", contents); + } + } + + System.out.println("Total number of tests run: " + testCtr); + System.out.println("Total number of errors: " + errors); + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + private String getContent(String className) { + StringBuilder annoData = new StringBuilder(); + + switch(className) { + case "DeprecatedonBoth": + annoData.append(Helper.ContentVars.DEPRECATED.getVal()) + .append(Helper.ContentVars.CONTAINERFOR.getVal()) + .append(Helper.ContentVars.CONTAINER.getVal()) + .append(Helper.ContentVars.DEPRECATED.getVal()) + .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.BASE.getVal()); + break; + case "DeprecatedonBase": + annoData.append(Helper.ContentVars.CONTAINERFOR.getVal()) + .append(Helper.ContentVars.CONTAINER.getVal()) + .append(Helper.ContentVars.DEPRECATED.getVal()) + .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.BASE.getVal()); + break; + case "DeprecatedonContainer": + annoData.append(Helper.ContentVars.DEPRECATED.getVal()) + .append(Helper.ContentVars.CONTAINERFOR.getVal()) + .append(Helper.ContentVars.CONTAINER.getVal()) + .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.BASE.getVal()); + break; + } + + String contents = Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal() + + Helper.ContentVars.IMPORTDEPRECATED.getVal() + + annoData + + Helper.ContentVars.REPEATABLEANNO.getVal() + + "\nclass "+ className + "{}"; + return contents; + } + + private void error(String msg, String... contents) { + System.out.println("error: " + msg); + errors++; + if (contents.length == 1) { + System.out.println("Contents = " + contents[0]); + } + } +} diff -r 19d6ba779759 -r 2986e7052952 test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java Wed Nov 07 17:01:19 2012 -0800 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8002157 + * @author sogoel + * @summary Positive combo test for use of Documented on baseAnno/containerAnno + * @build Helper + * @compile DocumentedAnnoCombo.java + * @run main DocumentedAnnoCombo + */ + +import javax.tools.DiagnosticCollector; +import javax.tools.JavaFileObject; + +/* + * Generate valid test src for the use of @Documented on container anno + * or on both base anno and container anno. Both test src should compile. + * Repeating annotations used only on class for these generated test src. + */ +public class DocumentedAnnoCombo extends Helper { + static int errors = 0; + + enum TestCases { + DocumentedonBothAnno(true), + DocumentedonContainer(true); + + TestCases(boolean compile) { + this.compile = compile; + } + + boolean compile; + boolean shouldCompile() { + return compile; + } + } + + public static void main(String[] args) throws Exception { + new DocumentedAnnoCombo().runTest(); + } + + public void runTest() throws Exception { + boolean ok = false; + int testCtr = 0; + + // Create test source content + for (TestCases className : TestCases.values()) { + testCtr++; + String contents = getContent(className.toString()); + + // Compile the generated source file + DiagnosticCollector diagnostics = + new DiagnosticCollector(); + ok = compileCode(className.toString(), contents, diagnostics); + if (!ok) { + error("Class="+ className +" did not compile as expected", contents); + } else { + System.out.println("Test passed for className: " + className); + } + } + + System.out.println("Total number of tests run: " + testCtr); + System.out.println("Total number of errors: " + errors); + + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + private String getContent(String className) { + + StringBuilder annoData = new StringBuilder(); + switch(className) { + case "DocumentedonBothAnno": + annoData.append(Helper.ContentVars.DOCUMENTED.getVal()) + .append(Helper.ContentVars.CONTAINERFOR.getVal()) + .append(Helper.ContentVars.CONTAINER.getVal()) + .append(Helper.ContentVars.DOCUMENTED.getVal()) + .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.BASE.getVal()); + break; + case "DocumentedonContainer": + annoData.append(Helper.ContentVars.DOCUMENTED.getVal()) + .append(Helper.ContentVars.CONTAINERFOR.getVal()) + .append(Helper.ContentVars.CONTAINER.getVal()) + .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.BASE.getVal()); + break; + } + + String contents = Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal() + + Helper.ContentVars.IMPORTDOCUMENTED.getVal() + + annoData + + Helper.ContentVars.REPEATABLEANNO.getVal() + + "\nclass "+ className + "{}"; + return contents; + } + + private void error(String msg, String... contents) { + System.out.println("error: " + msg); + errors++; + if (contents.length == 1) { + System.out.println("Contents = " + contents[0]); + } + } +} + diff -r 19d6ba779759 -r 2986e7052952 test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java Wed Nov 07 17:01:19 2012 -0800 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Arrays; +import javax.tools.DiagnosticCollector; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; +import javax.tools.JavaCompiler.CompilationTask; + +public class Helper { + + enum ContentVars { + IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.ContainedBy;\n" + + "\nimport java.lang.annotation.ContainerFor;\n"), + IMPORTDEPRECATED("import java.lang.Deprecated;\n"), + IMPORTDOCUMENTED("import java.lang.annotation.Documented;\n"), + IMPORTINHERITED("import java.lang.annotation.Inherited;\n"), + IMPORTRETENTION("import java.lang.annotation.Retention;\n" + + "\nimport java.lang.annotation.RetentionPolicy;\n"), + CONTAINEDBY("\n@ContainedBy(FooContainer.class)\n"), + CONTAINERFOR("@ContainerFor(Foo.class)\n"), + CONTAINER("@interface FooContainer {\n" +" Foo[] value();\n}\n"), + BASE("@interface Foo {}\n"), + REPEATABLEANNO("\n@Foo() @Foo()"), + DEPRECATED("\n@Deprecated"), + DOCUMENTED("\n@Documented"), + INHERITED("\n@Inherited"), + RETENTION("@Retention(RetentionPolicy.#VAL)\n"); + + private String val; + + + private ContentVars(String val) { + this.val = val; + } + + public String getVal() { + return val; + } + } + + /* String template where /**/ /*gets replaced by repeating anno + * Used to generate test src for combo tests + * - BasicSyntaxCombo.java + * - TargetAnnoCombo.java + */ + public static final String template = + "/*PACKAGE*/\n" + + "//pkg test;\n\n" + + "/*TYPE*/ //class\n" + + "class #ClassName {\n" + + " /*FIELD*/ //instance var\n" + + " public int x = 0;\n\n" + + " /*FIELD*/ //Enum constants\n" + + " TestEnum testEnum;\n\n" + + " /*FIELD*/ // Static field\n" + + " public static int num;\n\n" + + " /*STATIC_INI*/\n" + + " static { \n" + "num = 10; \n }\n\n" + + " /*CONSTRUCTOR*/\n" + + " #ClassName() {}\n\n" + + " /*INSTANCE_INI*/\n" + + " { \n x = 10; \n }" + + " /*INNER_CLASS*/\n" + + " class innerClass {}\n" + + " /*METHOD*/\n" + + " void bar(/*PARAMETER*/ int baz) {\n" + + " /*LOCAL_VARIABLE*/\n" + + " int y = 0;\n" + + " }\n" + + "}\n\n" + + "/*TYPE*/ //Enum\n" + + "enum TestEnum {}\n\n" + + "/*TYPE*/ //Interface\n" + + "interface TestInterface {}\n\n" + + "/*TYPE*/\n" + + "/*ANNOTATION_TYPE*/\n" + + "@interface TestAnnotationType{}\n"; + + // Create and compile FileObject using values for className and contents + public static boolean compileCode(String className, String contents, + DiagnosticCollector diagnostics) { + boolean ok = false; + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + if (compiler == null) { + throw new RuntimeException("can't get javax.tools.JavaCompiler!"); + } + + JavaFileObject file = getFile(className, contents); + Iterable compilationUnit = Arrays.asList(file); + + CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnit); + ok = task.call(); + return ok; + + } + + // Compile a list of FileObjects + public static boolean compileCode(DiagnosticCollector diagnostics, Iterable files) { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + if (compiler == null) { + throw new RuntimeException("can't get javax.tools.JavaCompiler!"); + } + + CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, files); + boolean ok = task.call(); + return ok; + } + + static JavaFileObject getFile(String name, String code) { + JavaFileObject o = null; + try { + o = new JavaStringFileObject(name, code); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + return o; + } + static class JavaStringFileObject extends SimpleJavaFileObject { + final String theCode; + public JavaStringFileObject(String fileName, String theCode) throws URISyntaxException { + super(new URI("string:///" + fileName.replace('.','/') + ".java"), Kind.SOURCE); + this.theCode = theCode; + } + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return theCode; + } + } +} diff -r 19d6ba779759 -r 2986e7052952 test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java Wed Nov 07 17:01:19 2012 -0800 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8002157 + * @author sogoel + * @summary Positive combo test for use of Inherited on baseAnno/containerAnno + * @build Helper + * @compile InheritedAnnoCombo.java + * @run main InheritedAnnoCombo + */ + +import javax.tools.DiagnosticCollector; +import javax.tools.JavaFileObject; + +/* + * Generate valid test src for the use of @Inherited on container anno + * or on both base anno and container anno. Both test src should compile. + * Repeating annotations used only on class for these generated test src. + */ + +public class InheritedAnnoCombo extends Helper { + static int errors = 0; + enum TestCases { + InheritedonBothAnno(true), + InheritedonBase(true); + + TestCases(boolean compile) { + this.compile = compile; + } + + boolean compile; + boolean shouldCompile() { + return compile; + } + } + + public static void main(String[] args) throws Exception { + new InheritedAnnoCombo().runTest(); + } + + public void runTest() throws Exception { + int testCtr = 0; + boolean ok = false; + + // Create test source content + for (TestCases className : TestCases.values()) { + testCtr++; + String contents = getContent(className.toString()); + + // Compile the generated code + DiagnosticCollector diagnostics = + new DiagnosticCollector(); + ok = compileCode(className.toString(), contents, diagnostics); + + if (!ok) { + error("Class="+ className +" did not compile as expected", contents); + } else { + System.out.println("Test passed for className: " + className); + } + } + + System.out.println("Total number of tests run: " + testCtr); + System.out.println("Total number of errors: " + errors); + + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + private String getContent(String className) { + + StringBuilder annoData = new StringBuilder(); + switch(className) { + case "InheritedonBothAnno": + annoData.append(Helper.ContentVars.INHERITED.getVal()) + .append(Helper.ContentVars.CONTAINERFOR.getVal()) + .append(Helper.ContentVars.CONTAINER.getVal()) + .append(Helper.ContentVars.INHERITED.getVal()) + .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.BASE.getVal()); + break; + case "InheritedonBase": + annoData.append(Helper.ContentVars.INHERITED.getVal()) + .append(Helper.ContentVars.CONTAINERFOR.getVal()) + .append(Helper.ContentVars.CONTAINER.getVal()) + .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.BASE.getVal()); + break; + } + + String contents = Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal() + + Helper.ContentVars.IMPORTINHERITED.getVal() + + annoData + + Helper.ContentVars.REPEATABLEANNO.getVal() + + "\nclass "+ className + "{}"; + return contents; + } + + private void error(String msg, String... contents) { + System.out.println("error: " + msg); + errors++; + if (contents.length == 1) { + System.out.println("Contents = " + contents[0]); + } + } +} + diff -r 19d6ba779759 -r 2986e7052952 test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java Wed Nov 07 17:01:19 2012 -0800 @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8002157 + * @author sogoel + * @summary Combo test for all possible combinations for Retention Values + * @build Helper + * @compile RetentionAnnoCombo.java + * @run main RetentionAnnoCombo + */ + +import java.util.HashMap; +import java.util.Map; + +import javax.tools.DiagnosticCollector; +import javax.tools.JavaFileObject; +import javax.tools.Diagnostic; + +/* + * Generate all combinations for the use of @Retention on base anno or container + * anno or both. The test passes if valid test src compile as expected and + * and invalid test src fail as expected. + * Repeating annotations used only on class for these generated test src. + */ + +public class RetentionAnnoCombo extends Helper { + static int errors = 0; + static boolean exitMode = false; + static { + String exitOnFail = System.getenv("EXIT_ON_FAIL"); + if (exitOnFail == null || exitOnFail == "" ) { + exitMode = false; + } + else { + if (exitOnFail.equalsIgnoreCase("YES") || + exitOnFail.equalsIgnoreCase("Y") || + exitOnFail.equalsIgnoreCase("TRUE") || + exitOnFail.equalsIgnoreCase("T")) { + exitMode = true; + } + } + } + + public static void main(String args[]) throws Exception { + new RetentionAnnoCombo().runTest(); + } + + public void runTest() throws Exception { + + /* 4x4 matrix for Retention values SOURCE, DEFAULT, CLASS, RUNTIME + * i -> Retention value on ContainerAnno + * j -> Retention value on BaseAnno + * 1 -> retention value combo should compile + */ + int[][] retention = { {1, 0, 0, 0}, + {1, 1, 1, 0}, + {1, 1, 1, 0}, + {1, 1, 1, 1} }; + + Map retMap = setRetentionValMatrix(); + String contents = ""; + boolean result = false; + int testCtr = 0; + for (int i = 0; i < 4 ; i ++) { + for (int j = 0; j < 4; j++ ) { + testCtr++; + String className = "RetentionTest_"+i+"_"+j; + contents = getContent(className, retMap, i, j); + if (retention[i][j] == 1) { + // Code generated should compile + result = getCompileResult(contents,className, true); + if (!result) { + error("FAIL: " + className + " did not compile as expected!", contents); + } + } else { + result = getCompileResult(contents,className, false); + if (!result) { + error("FAIL: " + className + " compiled unexpectedly!", contents); + } + } + if (result) { + System.out.println("Test passed for className = " + className); + } + } + } + + System.out.println("Total number of tests run: " + testCtr); + System.out.println("Total number of errors: " + errors); + + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + private boolean getCompileResult(String contents, String className, + boolean shouldCompile) throws Exception{ + + DiagnosticCollector diagnostics = + new DiagnosticCollector(); + boolean ok = compileCode(className, contents, diagnostics); + + String expectedErrKey = "compiler.err.invalid.containedby" + + ".annotation.retention"; + if (!shouldCompile && !ok) { + for (Diagnostic d : diagnostics.getDiagnostics()) { + if (!((d.getKind() == Diagnostic.Kind.ERROR) && + d.getCode().contains(expectedErrKey))) { + error("FAIL: Incorrect error given, expected = " + + expectedErrKey + ", Actual = " + d.getCode() + + " for className = " + className, contents); + } + } + } + + return (shouldCompile == ok); + } + + private Map setRetentionValMatrix() { + HashMap hm = new HashMap<>(); + hm.put(0,"SOURCE"); + hm.put(1,"DEFAULT"); + hm.put(2,"CLASS"); + hm.put(3,"RUNTIME"); + return hm; + } + + private String getContent(String className, Map retMap, + int i, int j) { + + String retContainerVal = retMap.get(i).toString(); + String retBaseVal = retMap.get(j).toString(); + String replacedRetBaseVal = "", replacedRetCAVal = ""; + String retention = Helper.ContentVars.RETENTION.getVal(); + + // @Retention is available as default for both base and container anno + if (retContainerVal.equalsIgnoreCase("DEFAULT") + && retBaseVal.equalsIgnoreCase("DEFAULT")) { + replacedRetBaseVal = ""; + replacedRetCAVal = ""; + // @Retention is available as default for container anno + } else if (retContainerVal.equalsIgnoreCase("DEFAULT")) { + replacedRetBaseVal = retention.replace("#VAL", retBaseVal); + replacedRetCAVal = ""; + // @Retention is available as default for base anno + } else if (retBaseVal.equalsIgnoreCase("DEFAULT")) { + replacedRetBaseVal = ""; + replacedRetCAVal = retention.replace("#VAL", retContainerVal); + // @Retention is not available as default for both base and container anno + } else { + replacedRetBaseVal = retention.replace("#VAL", retBaseVal); + replacedRetCAVal = retention.replace("#VAL", retContainerVal); + } + + StringBuilder annoData = new StringBuilder(); + annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal()) + .append(Helper.ContentVars.IMPORTRETENTION.getVal()) + .append(Helper.ContentVars.CONTAINERFOR.getVal()) + .append(replacedRetCAVal) + .append(Helper.ContentVars.CONTAINER.getVal()) + .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(replacedRetBaseVal) + .append(Helper.ContentVars.BASE.getVal()); + + String contents = annoData + + Helper.ContentVars.REPEATABLEANNO.getVal() + + "\nclass "+ className + "{}"; + return contents; + } + + private void error(String msg,String... contents) throws Exception { + System.out.println("error: " + msg); + errors++; + if (contents.length == 1) { + System.out.println("Contents = " + contents[0]); + } + // Test exits as soon as it gets a failure + if (exitMode) throw new Exception(); + } +} +