--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java Fri Mar 15 09:02:26 2013 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java Fri Mar 15 13:39:04 2013 +0100
@@ -21,245 +21,404 @@
* questions.
*/
-/**
+/*
* @test
- * @bug 7195131
- * @author sogoel
- * @summary Combo test for all possible combinations for Target values
- * @ignore 8008339 Test TargetAnnoCombo.java is broken
+ * @bug 7151010 8006547 8007766
+ * @summary Default test cases for running combinations for Target values
* @build Helper
- * @compile TargetAnnoCombo.java TestCaseGenerator.java
* @run main TargetAnnoCombo
*/
+import java.util.Set;
+import java.util.List;
import java.io.IOException;
+import java.lang.annotation.ElementType;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.EnumSet;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
-/*
- * TargetAnnoCombo gets a list of test case numbers using TestCaseGenerator.
- * For each of the test case number, @Target sets for base and container annotations
- * are determined, source files are generated, compiled, and the result is verified
- * based on if the @Target set for base and container is a positive or negative combination.
- *
- * @Target sets for base and container annotations are determined using a bit mapping of
- * 10 ElementType enum constants defined in JDK8.
- *
- * Bit Target value
- * 0 "ElementType.ANNOTATION_TYPE"
- * 1 "ElementType.CONSTRUCTOR"
- * 2 "ElementType.FIELD"
- * 3 "ElementType.LOCAL_VARIABLE"
- * 4 "ElementType.METHOD"
- * 5 "ElementType.TYPE"
- * 6 "ElementType.PARAMETER"
- * 7 "ElementType.PACKAGE"
- * 8 "ElementType.TYPE_USE"
- * 9 "ElementType.TYPE_PARAMETER"
- *
- * Group 1:
- * 20 bits mapping, representing a test case number, is used for all target set
- * combinations ( 0 to 1048575 ) including empty @Target sets => @Target({}).
- * From this 20 bits, 10 bits are for base followed by 10 bits for container
- * where each bit maps to an ElementType enum constant defined in JDK8.
- *
- * Examples:
- * Test case number: 4, binary: 100 => container=100, base=[], container=["ElementType.FIELD"]
- * Test case number: 1003575, binary: 11110101000000110111 => base=1111010100, container=0000110111;
- * base=["ElementType.PARAMETER", "ElementType.TYPE_USE", "ElementType.METHOD", "ElementType.FIELD", "ElementType.PACKAGE", "ElementType.TYPE_PARAMETER"],
- * container=["ElementType.TYPE", "ElementType.METHOD", "ElementType.ANNOTATION_TYPE", "ElementType.CONSTRUCTOR", "ElementType.FIELD"]
- *
- * In the following groups, no @Target set is represented by null.
- * Group 2:
- * @Target is not defined on base.
- * Target sets for container are determined using the 10-bit binary number
- * resulting in 1024 test cases, mapping them to test case numbers from
- * 1048576 to (1048576 + 1023) => 1048576 to 1049599.
- *
- * Example:
- * Test case number: 1048587 => 1048587 - 1048576 = test case 11 in Group 2, binary: 1011 =>
- * base = null,
- * container = ["ElementType.ANNOTATION_TYPE","ElementType.CONSTRUCTOR","ElementType.LOCAL_VARIABLE"]
- *
- * Group 3:
- * @Target is not defined on container
- * Target sets for base are determined using the 10-bit binary number
- * resulting in 1024 test cases, mapping them to test case numbers from
- * 1049600 to (1049600 + 1023) => 1049600 to 1050623.
- *
- * Example:
- * Test case number: 1049708 => 1049708 - 1049600 = test case 108 in Group 3, binary: 1101100 =>
- * base = ["ElementType.FIELD", "ElementType.LOCAL_VARIABLE", "ElementType.TYPE", "ElementType.PARAMETER"],
- * container = null
- *
- * For the above group, test case number: 1049855 gives compiler error, JDK-8006547 filed
- *
- * Group 4:
- * @Target not defined for both base and container annotations.
- *
- * This is the last test and corresponds to test case number 1050624. base=null, container=null
- *
- * Examples to run this test:
- * 1. Run a specific test case number:
- * ${JTREG} -DTestCaseNum=10782 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
- * 2. Run specific number of tests:
- * ${JTREG} -DNumberOfTests=4 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
- * 3. Run specific number of tests with a seed:
- * ${JTREG} -DNumberOfTests=4 -DTestSeed=-972894659 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
- * 4. Run tests in default mode (number of tests = 1000):
- * ${JTREG} -DTestMode=DEFAULT -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
- * 5. Run all tests (FULL mode):
- * ${JTREG} -DTestMode=FULL -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
- *
- */
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.TYPE_USE;
+import static java.lang.annotation.ElementType.TYPE_PARAMETER;
public class TargetAnnoCombo {
- int errors = 0;
+
static final String TESTPKG = "testpkg";
- /*
- * Set it to true to get more debug information including base and
- * container target sets for a given test case number
- */
+
+ // Set it to true to get more debug information including base and container
+ // target sets for a given test case.
static final boolean DEBUG = false;
- // JDK 5/6/7/8 Targets
- static final String[] targetVals = {"ElementType.ANNOTATION_TYPE",
- "ElementType.CONSTRUCTOR", "ElementType.FIELD",
- "ElementType.LOCAL_VARIABLE", "ElementType.METHOD",
- "ElementType.TYPE", "ElementType.PARAMETER",
- "ElementType.PACKAGE", "ElementType.TYPE_USE",
- "ElementType.TYPE_PARAMETER"};
+ // Define constant target sets to be used for the combination of the target values.
+ final static Set<ElementType> noSet = null;
+ final static Set<ElementType> empty = EnumSet.noneOf(ElementType.class);
+
+ // [TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE,
+ // PACKAGE, TYPE_PARAMETER, TYPE_USE]
+ final static Set<ElementType> allTargets = EnumSet.allOf(ElementType.class);
+
+ // [TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE,
+ // PACKAGE]
+ final static Set<ElementType> jdk7 = EnumSet.range(TYPE, PACKAGE);
+
+ // [TYPE_USE, TYPE_PARAMETER]
+ final static Set<ElementType> jdk8 = EnumSet.range(TYPE_PARAMETER, TYPE_USE);
+
+ // List of test cases to run. This list is created in generate().
+ // To run a specific test cases add case number in @run main line.
+ List<TestCase> testCases = new ArrayList<TestCase>();
+
+ int errors = 0;
+
+ // Identify test cases that fail.
+ enum IgnoreKind {
+ RUN,
+ IGNORE
+ };
+
+ private class TestCase {
+
+ private Set<ElementType> baseAnnotations;
+ private Set<ElementType> containerAnnotations;
+ private IgnoreKind ignore;
+
+ public TestCase(Set<ElementType> baseAnnotations, Set<ElementType> containerAnnotations) {
+ this(baseAnnotations, containerAnnotations, IgnoreKind.RUN);
+ }
+
+ public TestCase(Set<ElementType> baseAnnotations, Set<ElementType> containerAnnotations,
+ IgnoreKind ignoreKind) {
+ this.baseAnnotations = baseAnnotations;
+ this.containerAnnotations = containerAnnotations;
+ this.ignore = ignoreKind;
+ }
+
+ public Set getBaseAnnotations() {
+ return baseAnnotations;
+ }
+
+ public Set getContainerAnnotations() {
+ return containerAnnotations;
+ }
+
+ public boolean isIgnored() {
+ return ignore == IgnoreKind.IGNORE;
+ }
- // TYPE_USE and TYPE_PARAMETER (added in JDK8) are not part of default Target set
- static final int DEFAULT_TARGET_CNT = 8;
+ // Determine if a testCase should compile or not.
+ private boolean isValidSubSet() {
+ /*
+ * RULE 1: conAnnoTarget should be a subset of baseAnnoTarget
+ * RULE 2: For empty @Target ({}) - annotation cannot be applied anywhere
+ * - Empty sets for both is valid
+ * - Empty baseTarget set is invalid with non-empty conTarget set
+ * - Non-empty baseTarget set is valid with empty conTarget set
+ * RULE 3: For no @Target specified - annotation can be applied to any JDK 7 targets
+ * - No @Target for both is valid
+ * - No @Target for baseTarget set with @Target conTarget set is valid
+ * - @Target for baseTarget set with no @Target for conTarget is invalid
+ */
+
+
+ /* If baseAnno has no @Target, Foo can be either applied to @Target specified
+ * for container annotation else will be applicable for all default targets
+ * if no @Target is present for container annotation.
+ * In both cases, the set will be a valid set with no @Target for base annotation
+ */
+ if (baseAnnotations == null) {
+ if (containerAnnotations == null) {
+ return true;
+ }
+ return !(containerAnnotations.contains(TYPE_USE) ||
+ containerAnnotations.contains(TYPE_PARAMETER));
+ }
+
+ Set<ElementType> tempBaseSet = EnumSet.noneOf(ElementType.class);
+ tempBaseSet.addAll(baseAnnotations);
+ // If BaseAnno has TYPE, then ANNOTATION_TYPE is allowed by default.
+ if (baseAnnotations.contains(TYPE)) {
+ tempBaseSet.add(ANNOTATION_TYPE);
+ }
+
+ // If containerAnno has no @Target, only valid case if baseAnnoTarget has
+ // all targets defined else invalid set.
+ if (containerAnnotations == null) {
+ return tempBaseSet.containsAll(jdk7);
+ }
+
+ // At this point, neither conAnnoTarget or baseAnnoTarget are null.
+ if (containerAnnotations.isEmpty()) {
+ return true;
+ }
+
+ // At this point, conAnnoTarget is non-empty.
+ if (baseAnnotations.isEmpty()) {
+ return false;
+ }
+
+ // At this point, neither conAnnoTarget or baseAnnoTarget are empty.
+ return tempBaseSet.containsAll(containerAnnotations);
+ }
+ }
public static void main(String args[]) throws Exception {
-
- /* maxTestNum = (base and container combinations of targetVals elems [0 - 1048575 combos])
- * + (combinations where base or container has no Target [1024 combos])
- * + (no -1 even though 1st test is number 0 as last test is where both
- * base and container have no target)
- */
-
- int maxTestNum = (int)Math.pow(2, 2*targetVals.length) + 2*(int)Math.pow(2, targetVals.length);
- TestCaseGenerator tcg = new TestCaseGenerator(maxTestNum);
TargetAnnoCombo tac = new TargetAnnoCombo();
-
- int testCtr = 0;
- int testCase = -1;
- while ( (testCase=tcg.getNextTestCase()) != -1 ) {
- tac.executeTestCase(testCase, maxTestNum);
- testCtr++;
+ // Generates all test cases to be run.
+ tac.generate();
+ List<Integer> cases = new ArrayList<Integer>();
+ for (int i = 0; i < args.length; i++) {
+ cases.add(Integer.parseInt(args[i]));
}
-
- System.out.println("Total tests run: " + testCtr);
- if (tac.errors > 0)
- throw new Exception(tac.errors + " errors found");
+ if (cases.isEmpty()) {
+ tac.run();
+ } else {
+ for (int index : cases) {
+ tac.executeTestCase(tac.testCases.get(index), index);
+ }
+ }
}
- /*
- * For given testCase, determine the base and container annotation Target sets,
- * get if testCase should compile, get test source file(s), get compilation result and verify.
- *
- */
- private void executeTestCase(int testCase, int maxTestNum) {
-
- // Determine base and container annotation Target sets for the testCase
- Set<String> baseAnnoTarget = null;
- Set<String> conAnnoTarget = null;
-
- //Number of base and container combinations [0 - 1048575 combos]
- int baseContCombos = (int)Math.pow(2, 2*targetVals.length);
- //Number of either base or container combinations when one of them has no @Target [1024 combos]
- int targetValsCombos = (int)Math.pow(2, targetVals.length);
-
- if (testCase >= baseContCombos) {
- //Base annotation do not have @Target
- if (testCase < baseContCombos + targetValsCombos) {
- baseAnnoTarget = null;
- conAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos));
- } else if (testCase < baseContCombos + 2*targetValsCombos) {
- //Container annotation do not have @Target
- baseAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos - targetValsCombos));
- conAnnoTarget = null;
- } else {
- //Both Base and Container annotation do not have @Target
- baseAnnoTarget = null;
- conAnnoTarget = null;
+ private void generate() {
+ // Adding test cases to run.
+ testCases.addAll(Arrays.asList(
+ // No base target against no container target.
+ new TestCase(noSet, noSet),
+ // No base target against empty container target.
+ new TestCase(noSet, empty),
+ // No base target against TYPE_USE only container target.
+ new TestCase(noSet, less(jdk8, TYPE_PARAMETER)),
+ // No base target against TYPE_PARAMETER only container target.
+ new TestCase(noSet, less(jdk8, TYPE_USE)),
+ // No base target against TYPE_USE + TYPE_PARAMETER only container target.
+ new TestCase(noSet, jdk8),
+ // No base target against TYPE_USE + some selection of jdk7 targets.
+ new TestCase(noSet,
+ plus(EnumSet.range(TYPE, LOCAL_VARIABLE), TYPE_USE)),
+ // No base target against TYPE_PARAMETER + some selection of jdk7 targets.
+ new TestCase(noSet,
+ plus(EnumSet.range(TYPE, LOCAL_VARIABLE), TYPE_PARAMETER)),
+ // No base target against each jdk7 target alone as container target.
+ new TestCase(noSet, plus(empty, TYPE)),
+ new TestCase(noSet, plus(empty, PARAMETER)),
+ new TestCase(noSet, plus(empty, PACKAGE)),
+ new TestCase(noSet, plus(empty, METHOD)),
+ new TestCase(noSet, plus(empty, LOCAL_VARIABLE)),
+ new TestCase(noSet, plus(empty, FIELD)),
+ new TestCase(noSet, plus(empty, CONSTRUCTOR)),
+ new TestCase(noSet, plus(empty, ANNOTATION_TYPE)),
+ // Empty base target against no container target.
+ new TestCase(empty, noSet),
+ // Empty base target against empty container target.
+ new TestCase(empty, empty),
+ // Empty base target against any lone container target.
+ new TestCase(empty, plus(empty, TYPE)),
+ new TestCase(empty, plus(empty, PARAMETER)),
+ new TestCase(empty, plus(empty, PACKAGE)),
+ new TestCase(empty, plus(empty, METHOD)),
+ new TestCase(empty, plus(empty, LOCAL_VARIABLE)),
+ new TestCase(empty, plus(empty, FIELD)),
+ new TestCase(empty, plus(empty, CONSTRUCTOR)),
+ new TestCase(empty, plus(empty, ANNOTATION_TYPE)),
+ new TestCase(empty, less(jdk8, TYPE_USE)),
+ new TestCase(empty, less(jdk8, TYPE_PARAMETER)),
+ // No container target against all all-but one jdk7 targets.
+ new TestCase(less(jdk7, TYPE), noSet),
+ new TestCase(less(jdk7, PARAMETER), noSet),
+ new TestCase(less(jdk7, PACKAGE), noSet),
+ new TestCase(less(jdk7, METHOD), noSet),
+ new TestCase(less(jdk7, LOCAL_VARIABLE), noSet),
+ new TestCase(less(jdk7, FIELD), noSet),
+ new TestCase(less(jdk7, CONSTRUCTOR), noSet),
+ new TestCase(less(jdk7, ANNOTATION_TYPE), noSet),
+ // No container against all but TYPE and ANNOTATION_TYPE
+ new TestCase(less(jdk7, TYPE, ANNOTATION_TYPE), noSet),
+ // No container against jdk7 targets.
+ new TestCase(jdk7, noSet),
+ // No container against jdk7 targets plus one or both of TYPE_USE, TYPE_PARAMETER
+ new TestCase(plus(jdk7, TYPE_USE), noSet),
+ new TestCase(plus(jdk7, TYPE_PARAMETER), noSet),
+ new TestCase(allTargets, noSet),
+ // Empty container target against any lone target.
+ new TestCase(plus(empty, TYPE), empty),
+ new TestCase(plus(empty, PARAMETER), empty),
+ new TestCase(plus(empty, PACKAGE), empty),
+ new TestCase(plus(empty, METHOD), empty),
+ new TestCase(plus(empty, LOCAL_VARIABLE), empty),
+ new TestCase(plus(empty, FIELD), empty),
+ new TestCase(plus(empty, CONSTRUCTOR), empty),
+ new TestCase(plus(empty, ANNOTATION_TYPE), empty),
+ new TestCase(plus(empty, TYPE_USE), empty),
+ new TestCase(plus(empty, TYPE_PARAMETER), empty),
+ // All base targets against all container targets.
+ new TestCase(allTargets, allTargets),
+ // All base targets against all but one container targets.
+ new TestCase(allTargets, less(allTargets, TYPE)),
+ new TestCase(allTargets, less(allTargets, PARAMETER)),
+ new TestCase(allTargets, less(allTargets, PACKAGE)),
+ new TestCase(allTargets, less(allTargets, METHOD)),
+ new TestCase(allTargets, less(allTargets, LOCAL_VARIABLE)),
+ new TestCase(allTargets, less(allTargets, FIELD)),
+ new TestCase(allTargets, less(allTargets, CONSTRUCTOR)),
+ new TestCase(allTargets, less(allTargets, ANNOTATION_TYPE)),
+ new TestCase(allTargets, less(allTargets, TYPE_USE)),
+ new TestCase(allTargets, less(allTargets, TYPE_PARAMETER)),
+ // All container targets against all but one base targets.
+ new TestCase(less(allTargets, TYPE), allTargets),
+ new TestCase(less(allTargets, PARAMETER), allTargets),
+ new TestCase(less(allTargets, PACKAGE), allTargets),
+ new TestCase(less(allTargets, METHOD), allTargets),
+ new TestCase(less(allTargets, LOCAL_VARIABLE), allTargets),
+ new TestCase(less(allTargets, FIELD), allTargets),
+ new TestCase(less(allTargets, CONSTRUCTOR), allTargets),
+ new TestCase(less(allTargets, ANNOTATION_TYPE), allTargets),
+ new TestCase(less(allTargets, TYPE_USE), allTargets),
+ new TestCase(less(allTargets, TYPE_PARAMETER), allTargets)));
+ // Generates 100 test cases for any lone base target contained in Set
+ // allTargets against any lone container target.
+ for (ElementType b : allTargets) {
+ for (ElementType c : allTargets) {
+ testCases.add(new TestCase(plus(empty, b), plus(empty, c)));
}
- } else {
- //TestCase number is represented as 10-bits for base followed by container bits
- String bin = Integer.toBinaryString(testCase);
- String base="", cont=bin;
- if (bin.length() > targetVals.length){
- base = bin.substring(0, bin.length() - targetVals.length);
- cont = bin.substring(bin.length() - targetVals.length,bin.length());
- }
- baseAnnoTarget = getSetFromBitVec(base);
- conAnnoTarget = getSetFromBitVec(cont);
}
-
- debugPrint("Test case number = " + testCase + " => binary = " + Integer.toBinaryString(testCase));
- debugPrint(" => baseAnnoTarget = " + baseAnnoTarget);
- debugPrint(" => containerAnnoTarget = " + conAnnoTarget);
+ }
- // Determine if a testCase should compile or not
- String className = "TC" + testCase;
- boolean shouldCompile = isValidSubSet(baseAnnoTarget, conAnnoTarget);
-
- // Get test source file(s)
- Iterable<? extends JavaFileObject> files = getFileList(className, baseAnnoTarget,
- conAnnoTarget, shouldCompile);
+ void run() throws Exception {
+ int testCtr = 0;
+ for (TestCase tc : testCases) {
+ if (!tc.isIgnored()) {
+ executeTestCase(tc, testCases.indexOf(tc));
+ testCtr++;
+ }
+ }
+ System.out.println("Total tests run: " + testCtr);
+ if (errors > 0) {
+ throw new Exception(errors + " errors found");
+ }
+ }
- // Get result of compiling test src file(s)
- boolean result = getCompileResult(className, shouldCompile, files);
+ private void executeTestCase(TestCase testCase, int index) {
+ debugPrint("Test case number = " + index);
+ debugPrint(" => baseAnnoTarget = " + testCase.getBaseAnnotations());
+ debugPrint(" => containerAnnoTarget = " + testCase.getContainerAnnotations());
- // List test src code if test fails
- if(!result) {
- System.out.println("FAIL: Test " + testCase);
+ String className = "TC" + index;
+ boolean shouldCompile = testCase.isValidSubSet();
+ Iterable<? extends JavaFileObject> files = getFileList(className, testCase, shouldCompile);
+ // Get result of compiling test src file(s).
+ boolean result = getCompileResult(className, shouldCompile, files);
+ // List test src code if test fails.
+ if (!result) {
+ System.out.println("FAIL: Test " + index);
try {
- for (JavaFileObject f: files) {
+ for (JavaFileObject f : files) {
System.out.println("File: " + f.getName() + "\n" + f.getCharContent(true));
}
} catch (IOException ioe) {
System.out.println("Exception: " + ioe);
}
} else {
- debugPrint("PASS: Test " + testCase);
+ debugPrint("PASS: Test " + index);
}
+
}
- // Get a Set<String> based on bits that are set to 1
- public Set<String> getSetFromBitVec(String bitVec) {
- Set<String> ret = new HashSet<>();
- char[] bit = bitVec.toCharArray();
- for (int i=bit.length-1, j=0; i>=0; i--, j++){
- if (bit[i] == '1') {
- ret.add(targetVals[j]);
+ // Create src code and corresponding JavaFileObjects.
+ private Iterable<? extends JavaFileObject> getFileList(String className,
+ TestCase testCase, boolean shouldCompile) {
+ Set<ElementType> baseAnnoTarget = testCase.getBaseAnnotations();
+ Set<ElementType> conAnnoTarget = testCase.getContainerAnnotations();
+ String srcContent = "";
+ String pkgInfoContent = "";
+ String template = Helper.template;
+ String baseTarget = "", conTarget = "";
+
+ String target = Helper.ContentVars.TARGET.getVal();
+ if (baseAnnoTarget != null) {
+ String tmp = target.replace("#VAL", convertToString(baseAnnoTarget).toString());
+ baseTarget = tmp.replace("[", "{").replace("]", "}");
+ }
+ if (conAnnoTarget != null) {
+ String tmp = target.replace("#VAL", convertToString(conAnnoTarget).toString());
+ conTarget = tmp.replace("[", "{").replace("]", "}");
+ }
+
+ String annoData = Helper.ContentVars.IMPORTSTMTS.getVal()
+ + conTarget
+ + Helper.ContentVars.CONTAINER.getVal()
+ + baseTarget
+ + Helper.ContentVars.REPEATABLE.getVal()
+ + Helper.ContentVars.BASE.getVal();
+
+ JavaFileObject pkgInfoFile = null;
+
+ // If shouldCompile = true and no @Target is specified for container annotation,
+ // then all 8 ElementType enum constants are applicable as targets for
+ // container annotation.
+ if (shouldCompile && conAnnoTarget == null) {
+ Set<ElementType> copySet = EnumSet.noneOf(ElementType.class);
+ copySet.addAll(jdk7);
+ conAnnoTarget = copySet;
+ }
+
+ if (shouldCompile) {
+ boolean isPkgCasePresent = conAnnoTarget.contains(PACKAGE);
+ String repeatableAnno = Helper.ContentVars.BASEANNO.getVal()
+ + " " + Helper.ContentVars.BASEANNO.getVal();
+ for (ElementType s : conAnnoTarget) {
+ String replaceStr = "/*" + s.name() + "*/";
+ if (s.name().equalsIgnoreCase("PACKAGE")) {
+ //Create packageInfo file.
+ String pkgInfoName = TESTPKG + "." + "package-info";
+ pkgInfoContent = repeatableAnno + "\npackage " + TESTPKG + ";" + annoData;
+ pkgInfoFile = Helper.getFile(pkgInfoName, pkgInfoContent);
+ } else {
+ template = template.replace(replaceStr, repeatableAnno);
+ if (!isPkgCasePresent) {
+ srcContent = template.replace(
+ "/*ANNODATA*/", annoData).replace("#ClassName", className);
+ } else {
+ replaceStr = "/*PACKAGE*/";
+ String tmp = template.replace(replaceStr, "package " + TESTPKG + ";");
+ srcContent = tmp.replace("#ClassName", className);
+ }
+ }
}
+ } else {
+ // For invalid cases, compilation should fail at declaration site.
+ template = "class #ClassName {}";
+ srcContent = annoData + template.replace("#ClassName", className);
}
- return ret;
+ JavaFileObject srcFile = Helper.getFile(className, srcContent);
+ Iterable<? extends JavaFileObject> files = null;
+ if (pkgInfoFile != null) {
+ files = Arrays.asList(pkgInfoFile, srcFile);
+ } else {
+ files = Arrays.asList(srcFile);
+ }
+ return files;
}
- // Compile the test source file(s) and return test result
+ // Compile the test source file(s) and return test result.
private boolean getCompileResult(String className, boolean shouldCompile,
Iterable<? extends JavaFileObject> files) {
DiagnosticCollector<JavaFileObject> diagnostics =
new DiagnosticCollector<JavaFileObject>();
Helper.compileCode(diagnostics, files);
-
- // Test case pass or fail
+ // Test case pass or fail.
boolean ok = false;
-
String errMesg = "";
int numDiags = diagnostics.getDiagnostics().size();
-
if (numDiags == 0) {
if (shouldCompile) {
debugPrint("Test passed, compiled as expected.");
@@ -270,201 +429,80 @@
}
} else {
if (shouldCompile) {
- // did not compile
+ // did not compile.
errMesg = "Test failed, did not compile.";
ok = false;
} else {
- // Error in compilation as expected
- String expectedErrKey = "compiler.err.invalid.repeatable." +
- "annotation.incompatible.target";
+ // Error in compilation as expected.
+ String expectedErrKey = "compiler.err.invalid.repeatable."
+ + "annotation.incompatible.target";
for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
- if((d.getKind() == Diagnostic.Kind.ERROR) &&
- d.getCode().contains(expectedErrKey)) {
- // Error message as expected
+ if ((d.getKind() == Diagnostic.Kind.ERROR)
+ && d.getCode().contains(expectedErrKey)) {
+ // Error message as expected.
debugPrint("Error message as expected.");
ok = true;
break;
} else {
- // error message is incorrect
+ // error message is incorrect.
ok = false;
}
}
if (!ok) {
- errMesg = "Incorrect error received when compiling " +
- className + ", expected: " + expectedErrKey;
+ errMesg = "Incorrect error received when compiling "
+ + className + ", expected: " + expectedErrKey;
}
}
}
- if(!ok) {
+ if (!ok) {
error(errMesg);
- for (Diagnostic<?> d : diagnostics.getDiagnostics())
+ for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
System.out.println(" Diags: " + d);
+ }
}
return ok;
}
- private void debugPrint(String string) {
- if(DEBUG)
- System.out.println(string);
+ private Set<ElementType> less(Set<ElementType> base, ElementType... sub) {
+ Set<ElementType> res = EnumSet.noneOf(ElementType.class);
+ res.addAll(base);
+ for (ElementType t : sub) {
+ res.remove(t);
+ }
+ return res;
+ }
+
+ private Set<ElementType> plus(Set<ElementType> base, ElementType... add) {
+ Set<ElementType> res = EnumSet.noneOf(ElementType.class);
+ res.addAll(base);
+ for (ElementType t : add) {
+ res.add(t);
+ }
+ return res;
}
- // Create src code and corresponding JavaFileObjects
- private Iterable<? extends JavaFileObject> getFileList(String className,
- Set<String> baseAnnoTarget, Set<String> conAnnoTarget,
- boolean shouldCompile) {
-
- String srcContent = "";
- String pkgInfoContent = "";
- String template = Helper.template;
- String baseTarget = "", conTarget = "";
-
- String target = Helper.ContentVars.TARGET.getVal();
- if(baseAnnoTarget != null) {
- baseTarget = target.replace("#VAL", baseAnnoTarget.toString())
- .replace("[", "{").replace("]", "}");
- }
- if(conAnnoTarget != null) {
- conTarget = target.replace("#VAL", conAnnoTarget.toString())
- .replace("[", "{").replace("]", "}");
+ // Iterate target set and add "ElementType." in front of every target type.
+ private List<String> convertToString(Set<ElementType> annoTarget) {
+ if (annoTarget == null) {
+ return null;
}
-
- String annoData = Helper.ContentVars.IMPORTSTMTS.getVal() +
- conTarget +
- Helper.ContentVars.CONTAINER.getVal() +
- baseTarget +
- Helper.ContentVars.REPEATABLE.getVal() +
- Helper.ContentVars.BASE.getVal();
-
- JavaFileObject pkgInfoFile = null;
-
- /*
- * If shouldCompile = true and no @Target is specified for container annotation,
- * then all 8 ElementType enum constants are applicable as targets for
- * container annotation.
- */
- if(shouldCompile && conAnnoTarget == null) {
- //conAnnoTarget = new HashSet<String>(Arrays.asList(targetVals));
- conAnnoTarget = getDefaultTargetSet();
+ List<String> annoTargets = new ArrayList<String>();
+ for (ElementType e : annoTarget) {
+ annoTargets.add("ElementType." + e.name());
}
-
- if(shouldCompile) {
- boolean isPkgCasePresent = new ArrayList<String>(conAnnoTarget).contains("ElementType.PACKAGE");
- String repeatableAnno = Helper.ContentVars.BASEANNO.getVal() + " " + Helper.ContentVars.BASEANNO.getVal();
- for(String s: conAnnoTarget) {
- s = s.replace("ElementType.","");
- String replaceStr = "/*"+s+"*/";
- if(s.equalsIgnoreCase("PACKAGE")) {
- //Create packageInfo file
- String pkgInfoName = TESTPKG + "." + "package-info";
- pkgInfoContent = repeatableAnno + "\npackage " + TESTPKG + ";" + annoData;
- pkgInfoFile = Helper.getFile(pkgInfoName, pkgInfoContent);
- } else {
- template = template.replace(replaceStr, repeatableAnno);
- //srcContent = template.replace("#ClassName",className);
- if(!isPkgCasePresent) {
- srcContent = template.replace("/*ANNODATA*/", annoData).replace("#ClassName",className);
- } else {
- replaceStr = "/*PACKAGE*/";
- srcContent = template.replace(replaceStr, "package " + TESTPKG + ";")
- .replace("#ClassName", className);
- }
- }
- }
- } else {
- // For invalid cases, compilation should fail at declaration site
- template = "class #ClassName {}";
- srcContent = annoData + template.replace("#ClassName",className);
- }
- JavaFileObject srcFile = Helper.getFile(className, srcContent);
- Iterable<? extends JavaFileObject> files = null;
- if(pkgInfoFile != null)
- files = Arrays.asList(pkgInfoFile,srcFile);
- else
- files = Arrays.asList(srcFile);
- return files;
+ return annoTargets;
}
- private Set<String> getDefaultTargetSet() {
- Set<String> defaultSet = new HashSet<>();
- int ctr = 0;
- for(String s : targetVals) {
- if(ctr++ < DEFAULT_TARGET_CNT) {
- defaultSet.add(s);
- }
+ private void debugPrint(String string) {
+ if (DEBUG) {
+ System.out.println(string);
}
- return defaultSet;
}
- private boolean isValidSubSet(Set<String> baseAnnoTarget, Set<String> conAnnoTarget) {
- /*
- * RULE 1: conAnnoTarget should be a subset of baseAnnoTarget
- * RULE 2: For empty @Target ({}) - annotation cannot be applied anywhere
- * - Empty sets for both is valid
- * - Empty baseTarget set is invalid with non-empty conTarget set
- * - Non-empty baseTarget set is valid with empty conTarget set
- * RULE 3: For no @Target specified - annotation can be applied to any JDK 7 targets
- * - No @Target for both is valid
- * - No @Target for baseTarget set with @Target conTarget set is valid
- * - @Target for baseTarget set with no @Target for conTarget is invalid
- */
-
-
- /* If baseAnno has no @Target, Foo can be either applied to @Target specified for container annotation
- * else will be applicable for all default targets if no @Target is present for container annotation.
- * In both cases, the set will be a valid set with no @Target for base annotation
- */
- if(baseAnnoTarget == null) {
- if(conAnnoTarget == null) return true;
- return !(conAnnoTarget.contains("ElementType.TYPE_USE") || conAnnoTarget.contains("ElementType.TYPE_PARAMETER"));
- }
-
- Set<String> tempBaseSet = new HashSet<>(baseAnnoTarget);
- // If BaseAnno has TYPE, then ANNOTATION_TYPE is allowed by default
- if(baseAnnoTarget.contains("ElementType.TYPE")) {
- tempBaseSet.add("ElementType.ANNOTATION_TYPE");
- }
-
- /*
- * If containerAnno has no @Target, only valid case if baseAnnoTarget has all targets defined
- * else invalid set
- */
- if(conAnnoTarget == null) {
- return (tempBaseSet.containsAll(getDefaultTargetSet()));
- }
-
- // At this point, neither conAnnoTarget or baseAnnoTarget are null
- if(conAnnoTarget.size() == 0) return true;
-
- // At this point, conAnnoTarget is non-empty
- if (baseAnnoTarget.size() == 0) return false;
-
- // At this point, neither conAnnoTarget or baseAnnoTarget are empty
- return tempBaseSet.containsAll(conAnnoTarget);
- }
-
- void error(String msg) {
+ private void error(String msg) {
System.out.println("ERROR: " + msg);
errors++;
}
-
- // Lists the start and end range for the given set of target vals
- void showGroups() {
- //Group 1: All target set combinations ( 0 to 1048575 ) including empty @Target sets => @Target({})
- int grpEnd1 = (int)Math.pow(2, 2*targetVals.length) - 1;
- System.out.println("[Group 1]: 0 - " + grpEnd1);
+}
- //Group 2: @Target not defined for base annotation ( 1048576 - 1049599 ).
- System.out.print("[Group 2]: " + (grpEnd1 + 1) + " - ");
- int grpEnd2 = grpEnd1 + 1 + (int)Math.pow(2, targetVals.length) - 1;
- System.out.println(grpEnd2);
-
- //Group 3: @Target not defined for container annotation ( 1049600 - 1050623 ).
- System.out.print("[Group 3]: " + (grpEnd2 + 1) + " - ");
- int grpEnd3 = grpEnd2 + 1 + (int)Math.pow(2, targetVals.length) - 1;
- System.out.println(grpEnd3);
-
- //Group 4: @Target not defined for both base and container annotations ( 1050624 ).
- System.out.println("[Group 4]: " + (grpEnd3 + 1));
- }
-}