1.1 --- a/test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java Fri Mar 15 09:02:26 2013 +0000 1.2 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java Fri Mar 15 13:39:04 2013 +0100 1.3 @@ -21,245 +21,404 @@ 1.4 * questions. 1.5 */ 1.6 1.7 -/** 1.8 +/* 1.9 * @test 1.10 - * @bug 7195131 1.11 - * @author sogoel 1.12 - * @summary Combo test for all possible combinations for Target values 1.13 - * @ignore 8008339 Test TargetAnnoCombo.java is broken 1.14 + * @bug 7151010 8006547 8007766 1.15 + * @summary Default test cases for running combinations for Target values 1.16 * @build Helper 1.17 - * @compile TargetAnnoCombo.java TestCaseGenerator.java 1.18 * @run main TargetAnnoCombo 1.19 */ 1.20 1.21 +import java.util.Set; 1.22 +import java.util.List; 1.23 import java.io.IOException; 1.24 +import java.lang.annotation.ElementType; 1.25 import java.util.ArrayList; 1.26 import java.util.Arrays; 1.27 -import java.util.HashSet; 1.28 -import java.util.Set; 1.29 +import java.util.EnumSet; 1.30 import javax.tools.Diagnostic; 1.31 import javax.tools.DiagnosticCollector; 1.32 import javax.tools.JavaFileObject; 1.33 1.34 -/* 1.35 - * TargetAnnoCombo gets a list of test case numbers using TestCaseGenerator. 1.36 - * For each of the test case number, @Target sets for base and container annotations 1.37 - * are determined, source files are generated, compiled, and the result is verified 1.38 - * based on if the @Target set for base and container is a positive or negative combination. 1.39 - * 1.40 - * @Target sets for base and container annotations are determined using a bit mapping of 1.41 - * 10 ElementType enum constants defined in JDK8. 1.42 - * 1.43 - * Bit Target value 1.44 - * 0 "ElementType.ANNOTATION_TYPE" 1.45 - * 1 "ElementType.CONSTRUCTOR" 1.46 - * 2 "ElementType.FIELD" 1.47 - * 3 "ElementType.LOCAL_VARIABLE" 1.48 - * 4 "ElementType.METHOD" 1.49 - * 5 "ElementType.TYPE" 1.50 - * 6 "ElementType.PARAMETER" 1.51 - * 7 "ElementType.PACKAGE" 1.52 - * 8 "ElementType.TYPE_USE" 1.53 - * 9 "ElementType.TYPE_PARAMETER" 1.54 - * 1.55 - * Group 1: 1.56 - * 20 bits mapping, representing a test case number, is used for all target set 1.57 - * combinations ( 0 to 1048575 ) including empty @Target sets => @Target({}). 1.58 - * From this 20 bits, 10 bits are for base followed by 10 bits for container 1.59 - * where each bit maps to an ElementType enum constant defined in JDK8. 1.60 - * 1.61 - * Examples: 1.62 - * Test case number: 4, binary: 100 => container=100, base=[], container=["ElementType.FIELD"] 1.63 - * Test case number: 1003575, binary: 11110101000000110111 => base=1111010100, container=0000110111; 1.64 - * base=["ElementType.PARAMETER", "ElementType.TYPE_USE", "ElementType.METHOD", "ElementType.FIELD", "ElementType.PACKAGE", "ElementType.TYPE_PARAMETER"], 1.65 - * container=["ElementType.TYPE", "ElementType.METHOD", "ElementType.ANNOTATION_TYPE", "ElementType.CONSTRUCTOR", "ElementType.FIELD"] 1.66 - * 1.67 - * In the following groups, no @Target set is represented by null. 1.68 - * Group 2: 1.69 - * @Target is not defined on base. 1.70 - * Target sets for container are determined using the 10-bit binary number 1.71 - * resulting in 1024 test cases, mapping them to test case numbers from 1.72 - * 1048576 to (1048576 + 1023) => 1048576 to 1049599. 1.73 - * 1.74 - * Example: 1.75 - * Test case number: 1048587 => 1048587 - 1048576 = test case 11 in Group 2, binary: 1011 => 1.76 - * base = null, 1.77 - * container = ["ElementType.ANNOTATION_TYPE","ElementType.CONSTRUCTOR","ElementType.LOCAL_VARIABLE"] 1.78 - * 1.79 - * Group 3: 1.80 - * @Target is not defined on container 1.81 - * Target sets for base are determined using the 10-bit binary number 1.82 - * resulting in 1024 test cases, mapping them to test case numbers from 1.83 - * 1049600 to (1049600 + 1023) => 1049600 to 1050623. 1.84 - * 1.85 - * Example: 1.86 - * Test case number: 1049708 => 1049708 - 1049600 = test case 108 in Group 3, binary: 1101100 => 1.87 - * base = ["ElementType.FIELD", "ElementType.LOCAL_VARIABLE", "ElementType.TYPE", "ElementType.PARAMETER"], 1.88 - * container = null 1.89 - * 1.90 - * For the above group, test case number: 1049855 gives compiler error, JDK-8006547 filed 1.91 - * 1.92 - * Group 4: 1.93 - * @Target not defined for both base and container annotations. 1.94 - * 1.95 - * This is the last test and corresponds to test case number 1050624. base=null, container=null 1.96 - * 1.97 - * Examples to run this test: 1.98 - * 1. Run a specific test case number: 1.99 - * ${JTREG} -DTestCaseNum=10782 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java 1.100 - * 2. Run specific number of tests: 1.101 - * ${JTREG} -DNumberOfTests=4 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java 1.102 - * 3. Run specific number of tests with a seed: 1.103 - * ${JTREG} -DNumberOfTests=4 -DTestSeed=-972894659 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java 1.104 - * 4. Run tests in default mode (number of tests = 1000): 1.105 - * ${JTREG} -DTestMode=DEFAULT -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java 1.106 - * 5. Run all tests (FULL mode): 1.107 - * ${JTREG} -DTestMode=FULL -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java 1.108 - * 1.109 - */ 1.110 +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; 1.111 +import static java.lang.annotation.ElementType.CONSTRUCTOR; 1.112 +import static java.lang.annotation.ElementType.FIELD; 1.113 +import static java.lang.annotation.ElementType.METHOD; 1.114 +import static java.lang.annotation.ElementType.PARAMETER; 1.115 +import static java.lang.annotation.ElementType.TYPE; 1.116 +import static java.lang.annotation.ElementType.PACKAGE; 1.117 +import static java.lang.annotation.ElementType.LOCAL_VARIABLE; 1.118 +import static java.lang.annotation.ElementType.TYPE_USE; 1.119 +import static java.lang.annotation.ElementType.TYPE_PARAMETER; 1.120 1.121 public class TargetAnnoCombo { 1.122 - int errors = 0; 1.123 + 1.124 static final String TESTPKG = "testpkg"; 1.125 - /* 1.126 - * Set it to true to get more debug information including base and 1.127 - * container target sets for a given test case number 1.128 - */ 1.129 + 1.130 + // Set it to true to get more debug information including base and container 1.131 + // target sets for a given test case. 1.132 static final boolean DEBUG = false; 1.133 1.134 - // JDK 5/6/7/8 Targets 1.135 - static final String[] targetVals = {"ElementType.ANNOTATION_TYPE", 1.136 - "ElementType.CONSTRUCTOR", "ElementType.FIELD", 1.137 - "ElementType.LOCAL_VARIABLE", "ElementType.METHOD", 1.138 - "ElementType.TYPE", "ElementType.PARAMETER", 1.139 - "ElementType.PACKAGE", "ElementType.TYPE_USE", 1.140 - "ElementType.TYPE_PARAMETER"}; 1.141 + // Define constant target sets to be used for the combination of the target values. 1.142 + final static Set<ElementType> noSet = null; 1.143 + final static Set<ElementType> empty = EnumSet.noneOf(ElementType.class); 1.144 1.145 - // TYPE_USE and TYPE_PARAMETER (added in JDK8) are not part of default Target set 1.146 - static final int DEFAULT_TARGET_CNT = 8; 1.147 + // [TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, 1.148 + // PACKAGE, TYPE_PARAMETER, TYPE_USE] 1.149 + final static Set<ElementType> allTargets = EnumSet.allOf(ElementType.class); 1.150 + 1.151 + // [TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, 1.152 + // PACKAGE] 1.153 + final static Set<ElementType> jdk7 = EnumSet.range(TYPE, PACKAGE); 1.154 + 1.155 + // [TYPE_USE, TYPE_PARAMETER] 1.156 + final static Set<ElementType> jdk8 = EnumSet.range(TYPE_PARAMETER, TYPE_USE); 1.157 + 1.158 + // List of test cases to run. This list is created in generate(). 1.159 + // To run a specific test cases add case number in @run main line. 1.160 + List<TestCase> testCases = new ArrayList<TestCase>(); 1.161 + 1.162 + int errors = 0; 1.163 + 1.164 + // Identify test cases that fail. 1.165 + enum IgnoreKind { 1.166 + RUN, 1.167 + IGNORE 1.168 + }; 1.169 + 1.170 + private class TestCase { 1.171 + 1.172 + private Set<ElementType> baseAnnotations; 1.173 + private Set<ElementType> containerAnnotations; 1.174 + private IgnoreKind ignore; 1.175 + 1.176 + public TestCase(Set<ElementType> baseAnnotations, Set<ElementType> containerAnnotations) { 1.177 + this(baseAnnotations, containerAnnotations, IgnoreKind.RUN); 1.178 + } 1.179 + 1.180 + public TestCase(Set<ElementType> baseAnnotations, Set<ElementType> containerAnnotations, 1.181 + IgnoreKind ignoreKind) { 1.182 + this.baseAnnotations = baseAnnotations; 1.183 + this.containerAnnotations = containerAnnotations; 1.184 + this.ignore = ignoreKind; 1.185 + } 1.186 + 1.187 + public Set getBaseAnnotations() { 1.188 + return baseAnnotations; 1.189 + } 1.190 + 1.191 + public Set getContainerAnnotations() { 1.192 + return containerAnnotations; 1.193 + } 1.194 + 1.195 + public boolean isIgnored() { 1.196 + return ignore == IgnoreKind.IGNORE; 1.197 + } 1.198 + 1.199 + // Determine if a testCase should compile or not. 1.200 + private boolean isValidSubSet() { 1.201 + /* 1.202 + * RULE 1: conAnnoTarget should be a subset of baseAnnoTarget 1.203 + * RULE 2: For empty @Target ({}) - annotation cannot be applied anywhere 1.204 + * - Empty sets for both is valid 1.205 + * - Empty baseTarget set is invalid with non-empty conTarget set 1.206 + * - Non-empty baseTarget set is valid with empty conTarget set 1.207 + * RULE 3: For no @Target specified - annotation can be applied to any JDK 7 targets 1.208 + * - No @Target for both is valid 1.209 + * - No @Target for baseTarget set with @Target conTarget set is valid 1.210 + * - @Target for baseTarget set with no @Target for conTarget is invalid 1.211 + */ 1.212 + 1.213 + 1.214 + /* If baseAnno has no @Target, Foo can be either applied to @Target specified 1.215 + * for container annotation else will be applicable for all default targets 1.216 + * if no @Target is present for container annotation. 1.217 + * In both cases, the set will be a valid set with no @Target for base annotation 1.218 + */ 1.219 + if (baseAnnotations == null) { 1.220 + if (containerAnnotations == null) { 1.221 + return true; 1.222 + } 1.223 + return !(containerAnnotations.contains(TYPE_USE) || 1.224 + containerAnnotations.contains(TYPE_PARAMETER)); 1.225 + } 1.226 + 1.227 + Set<ElementType> tempBaseSet = EnumSet.noneOf(ElementType.class); 1.228 + tempBaseSet.addAll(baseAnnotations); 1.229 + // If BaseAnno has TYPE, then ANNOTATION_TYPE is allowed by default. 1.230 + if (baseAnnotations.contains(TYPE)) { 1.231 + tempBaseSet.add(ANNOTATION_TYPE); 1.232 + } 1.233 + 1.234 + // If containerAnno has no @Target, only valid case if baseAnnoTarget has 1.235 + // all targets defined else invalid set. 1.236 + if (containerAnnotations == null) { 1.237 + return tempBaseSet.containsAll(jdk7); 1.238 + } 1.239 + 1.240 + // At this point, neither conAnnoTarget or baseAnnoTarget are null. 1.241 + if (containerAnnotations.isEmpty()) { 1.242 + return true; 1.243 + } 1.244 + 1.245 + // At this point, conAnnoTarget is non-empty. 1.246 + if (baseAnnotations.isEmpty()) { 1.247 + return false; 1.248 + } 1.249 + 1.250 + // At this point, neither conAnnoTarget or baseAnnoTarget are empty. 1.251 + return tempBaseSet.containsAll(containerAnnotations); 1.252 + } 1.253 + } 1.254 1.255 public static void main(String args[]) throws Exception { 1.256 - 1.257 - /* maxTestNum = (base and container combinations of targetVals elems [0 - 1048575 combos]) 1.258 - * + (combinations where base or container has no Target [1024 combos]) 1.259 - * + (no -1 even though 1st test is number 0 as last test is where both 1.260 - * base and container have no target) 1.261 - */ 1.262 - 1.263 - int maxTestNum = (int)Math.pow(2, 2*targetVals.length) + 2*(int)Math.pow(2, targetVals.length); 1.264 - TestCaseGenerator tcg = new TestCaseGenerator(maxTestNum); 1.265 TargetAnnoCombo tac = new TargetAnnoCombo(); 1.266 - 1.267 - int testCtr = 0; 1.268 - int testCase = -1; 1.269 - while ( (testCase=tcg.getNextTestCase()) != -1 ) { 1.270 - tac.executeTestCase(testCase, maxTestNum); 1.271 - testCtr++; 1.272 + // Generates all test cases to be run. 1.273 + tac.generate(); 1.274 + List<Integer> cases = new ArrayList<Integer>(); 1.275 + for (int i = 0; i < args.length; i++) { 1.276 + cases.add(Integer.parseInt(args[i])); 1.277 } 1.278 - 1.279 - System.out.println("Total tests run: " + testCtr); 1.280 - if (tac.errors > 0) 1.281 - throw new Exception(tac.errors + " errors found"); 1.282 + if (cases.isEmpty()) { 1.283 + tac.run(); 1.284 + } else { 1.285 + for (int index : cases) { 1.286 + tac.executeTestCase(tac.testCases.get(index), index); 1.287 + } 1.288 + } 1.289 } 1.290 1.291 - /* 1.292 - * For given testCase, determine the base and container annotation Target sets, 1.293 - * get if testCase should compile, get test source file(s), get compilation result and verify. 1.294 - * 1.295 - */ 1.296 - private void executeTestCase(int testCase, int maxTestNum) { 1.297 + private void generate() { 1.298 + // Adding test cases to run. 1.299 + testCases.addAll(Arrays.asList( 1.300 + // No base target against no container target. 1.301 + new TestCase(noSet, noSet), 1.302 + // No base target against empty container target. 1.303 + new TestCase(noSet, empty), 1.304 + // No base target against TYPE_USE only container target. 1.305 + new TestCase(noSet, less(jdk8, TYPE_PARAMETER)), 1.306 + // No base target against TYPE_PARAMETER only container target. 1.307 + new TestCase(noSet, less(jdk8, TYPE_USE)), 1.308 + // No base target against TYPE_USE + TYPE_PARAMETER only container target. 1.309 + new TestCase(noSet, jdk8), 1.310 + // No base target against TYPE_USE + some selection of jdk7 targets. 1.311 + new TestCase(noSet, 1.312 + plus(EnumSet.range(TYPE, LOCAL_VARIABLE), TYPE_USE)), 1.313 + // No base target against TYPE_PARAMETER + some selection of jdk7 targets. 1.314 + new TestCase(noSet, 1.315 + plus(EnumSet.range(TYPE, LOCAL_VARIABLE), TYPE_PARAMETER)), 1.316 + // No base target against each jdk7 target alone as container target. 1.317 + new TestCase(noSet, plus(empty, TYPE)), 1.318 + new TestCase(noSet, plus(empty, PARAMETER)), 1.319 + new TestCase(noSet, plus(empty, PACKAGE)), 1.320 + new TestCase(noSet, plus(empty, METHOD)), 1.321 + new TestCase(noSet, plus(empty, LOCAL_VARIABLE)), 1.322 + new TestCase(noSet, plus(empty, FIELD)), 1.323 + new TestCase(noSet, plus(empty, CONSTRUCTOR)), 1.324 + new TestCase(noSet, plus(empty, ANNOTATION_TYPE)), 1.325 + // Empty base target against no container target. 1.326 + new TestCase(empty, noSet), 1.327 + // Empty base target against empty container target. 1.328 + new TestCase(empty, empty), 1.329 + // Empty base target against any lone container target. 1.330 + new TestCase(empty, plus(empty, TYPE)), 1.331 + new TestCase(empty, plus(empty, PARAMETER)), 1.332 + new TestCase(empty, plus(empty, PACKAGE)), 1.333 + new TestCase(empty, plus(empty, METHOD)), 1.334 + new TestCase(empty, plus(empty, LOCAL_VARIABLE)), 1.335 + new TestCase(empty, plus(empty, FIELD)), 1.336 + new TestCase(empty, plus(empty, CONSTRUCTOR)), 1.337 + new TestCase(empty, plus(empty, ANNOTATION_TYPE)), 1.338 + new TestCase(empty, less(jdk8, TYPE_USE)), 1.339 + new TestCase(empty, less(jdk8, TYPE_PARAMETER)), 1.340 + // No container target against all all-but one jdk7 targets. 1.341 + new TestCase(less(jdk7, TYPE), noSet), 1.342 + new TestCase(less(jdk7, PARAMETER), noSet), 1.343 + new TestCase(less(jdk7, PACKAGE), noSet), 1.344 + new TestCase(less(jdk7, METHOD), noSet), 1.345 + new TestCase(less(jdk7, LOCAL_VARIABLE), noSet), 1.346 + new TestCase(less(jdk7, FIELD), noSet), 1.347 + new TestCase(less(jdk7, CONSTRUCTOR), noSet), 1.348 + new TestCase(less(jdk7, ANNOTATION_TYPE), noSet), 1.349 + // No container against all but TYPE and ANNOTATION_TYPE 1.350 + new TestCase(less(jdk7, TYPE, ANNOTATION_TYPE), noSet), 1.351 + // No container against jdk7 targets. 1.352 + new TestCase(jdk7, noSet), 1.353 + // No container against jdk7 targets plus one or both of TYPE_USE, TYPE_PARAMETER 1.354 + new TestCase(plus(jdk7, TYPE_USE), noSet), 1.355 + new TestCase(plus(jdk7, TYPE_PARAMETER), noSet), 1.356 + new TestCase(allTargets, noSet), 1.357 + // Empty container target against any lone target. 1.358 + new TestCase(plus(empty, TYPE), empty), 1.359 + new TestCase(plus(empty, PARAMETER), empty), 1.360 + new TestCase(plus(empty, PACKAGE), empty), 1.361 + new TestCase(plus(empty, METHOD), empty), 1.362 + new TestCase(plus(empty, LOCAL_VARIABLE), empty), 1.363 + new TestCase(plus(empty, FIELD), empty), 1.364 + new TestCase(plus(empty, CONSTRUCTOR), empty), 1.365 + new TestCase(plus(empty, ANNOTATION_TYPE), empty), 1.366 + new TestCase(plus(empty, TYPE_USE), empty), 1.367 + new TestCase(plus(empty, TYPE_PARAMETER), empty), 1.368 + // All base targets against all container targets. 1.369 + new TestCase(allTargets, allTargets), 1.370 + // All base targets against all but one container targets. 1.371 + new TestCase(allTargets, less(allTargets, TYPE)), 1.372 + new TestCase(allTargets, less(allTargets, PARAMETER)), 1.373 + new TestCase(allTargets, less(allTargets, PACKAGE)), 1.374 + new TestCase(allTargets, less(allTargets, METHOD)), 1.375 + new TestCase(allTargets, less(allTargets, LOCAL_VARIABLE)), 1.376 + new TestCase(allTargets, less(allTargets, FIELD)), 1.377 + new TestCase(allTargets, less(allTargets, CONSTRUCTOR)), 1.378 + new TestCase(allTargets, less(allTargets, ANNOTATION_TYPE)), 1.379 + new TestCase(allTargets, less(allTargets, TYPE_USE)), 1.380 + new TestCase(allTargets, less(allTargets, TYPE_PARAMETER)), 1.381 + // All container targets against all but one base targets. 1.382 + new TestCase(less(allTargets, TYPE), allTargets), 1.383 + new TestCase(less(allTargets, PARAMETER), allTargets), 1.384 + new TestCase(less(allTargets, PACKAGE), allTargets), 1.385 + new TestCase(less(allTargets, METHOD), allTargets), 1.386 + new TestCase(less(allTargets, LOCAL_VARIABLE), allTargets), 1.387 + new TestCase(less(allTargets, FIELD), allTargets), 1.388 + new TestCase(less(allTargets, CONSTRUCTOR), allTargets), 1.389 + new TestCase(less(allTargets, ANNOTATION_TYPE), allTargets), 1.390 + new TestCase(less(allTargets, TYPE_USE), allTargets), 1.391 + new TestCase(less(allTargets, TYPE_PARAMETER), allTargets))); 1.392 + // Generates 100 test cases for any lone base target contained in Set 1.393 + // allTargets against any lone container target. 1.394 + for (ElementType b : allTargets) { 1.395 + for (ElementType c : allTargets) { 1.396 + testCases.add(new TestCase(plus(empty, b), plus(empty, c))); 1.397 + } 1.398 + } 1.399 + } 1.400 1.401 - // Determine base and container annotation Target sets for the testCase 1.402 - Set<String> baseAnnoTarget = null; 1.403 - Set<String> conAnnoTarget = null; 1.404 + void run() throws Exception { 1.405 + int testCtr = 0; 1.406 + for (TestCase tc : testCases) { 1.407 + if (!tc.isIgnored()) { 1.408 + executeTestCase(tc, testCases.indexOf(tc)); 1.409 + testCtr++; 1.410 + } 1.411 + } 1.412 + System.out.println("Total tests run: " + testCtr); 1.413 + if (errors > 0) { 1.414 + throw new Exception(errors + " errors found"); 1.415 + } 1.416 + } 1.417 1.418 - //Number of base and container combinations [0 - 1048575 combos] 1.419 - int baseContCombos = (int)Math.pow(2, 2*targetVals.length); 1.420 - //Number of either base or container combinations when one of them has no @Target [1024 combos] 1.421 - int targetValsCombos = (int)Math.pow(2, targetVals.length); 1.422 + private void executeTestCase(TestCase testCase, int index) { 1.423 + debugPrint("Test case number = " + index); 1.424 + debugPrint(" => baseAnnoTarget = " + testCase.getBaseAnnotations()); 1.425 + debugPrint(" => containerAnnoTarget = " + testCase.getContainerAnnotations()); 1.426 1.427 - if (testCase >= baseContCombos) { 1.428 - //Base annotation do not have @Target 1.429 - if (testCase < baseContCombos + targetValsCombos) { 1.430 - baseAnnoTarget = null; 1.431 - conAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos)); 1.432 - } else if (testCase < baseContCombos + 2*targetValsCombos) { 1.433 - //Container annotation do not have @Target 1.434 - baseAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos - targetValsCombos)); 1.435 - conAnnoTarget = null; 1.436 - } else { 1.437 - //Both Base and Container annotation do not have @Target 1.438 - baseAnnoTarget = null; 1.439 - conAnnoTarget = null; 1.440 - } 1.441 - } else { 1.442 - //TestCase number is represented as 10-bits for base followed by container bits 1.443 - String bin = Integer.toBinaryString(testCase); 1.444 - String base="", cont=bin; 1.445 - if (bin.length() > targetVals.length){ 1.446 - base = bin.substring(0, bin.length() - targetVals.length); 1.447 - cont = bin.substring(bin.length() - targetVals.length,bin.length()); 1.448 - } 1.449 - baseAnnoTarget = getSetFromBitVec(base); 1.450 - conAnnoTarget = getSetFromBitVec(cont); 1.451 - } 1.452 - 1.453 - debugPrint("Test case number = " + testCase + " => binary = " + Integer.toBinaryString(testCase)); 1.454 - debugPrint(" => baseAnnoTarget = " + baseAnnoTarget); 1.455 - debugPrint(" => containerAnnoTarget = " + conAnnoTarget); 1.456 - 1.457 - // Determine if a testCase should compile or not 1.458 - String className = "TC" + testCase; 1.459 - boolean shouldCompile = isValidSubSet(baseAnnoTarget, conAnnoTarget); 1.460 - 1.461 - // Get test source file(s) 1.462 - Iterable<? extends JavaFileObject> files = getFileList(className, baseAnnoTarget, 1.463 - conAnnoTarget, shouldCompile); 1.464 - 1.465 - // Get result of compiling test src file(s) 1.466 + String className = "TC" + index; 1.467 + boolean shouldCompile = testCase.isValidSubSet(); 1.468 + Iterable<? extends JavaFileObject> files = getFileList(className, testCase, shouldCompile); 1.469 + // Get result of compiling test src file(s). 1.470 boolean result = getCompileResult(className, shouldCompile, files); 1.471 - 1.472 - // List test src code if test fails 1.473 - if(!result) { 1.474 - System.out.println("FAIL: Test " + testCase); 1.475 + // List test src code if test fails. 1.476 + if (!result) { 1.477 + System.out.println("FAIL: Test " + index); 1.478 try { 1.479 - for (JavaFileObject f: files) { 1.480 + for (JavaFileObject f : files) { 1.481 System.out.println("File: " + f.getName() + "\n" + f.getCharContent(true)); 1.482 } 1.483 } catch (IOException ioe) { 1.484 System.out.println("Exception: " + ioe); 1.485 } 1.486 } else { 1.487 - debugPrint("PASS: Test " + testCase); 1.488 + debugPrint("PASS: Test " + index); 1.489 } 1.490 + 1.491 } 1.492 1.493 - // Get a Set<String> based on bits that are set to 1 1.494 - public Set<String> getSetFromBitVec(String bitVec) { 1.495 - Set<String> ret = new HashSet<>(); 1.496 - char[] bit = bitVec.toCharArray(); 1.497 - for (int i=bit.length-1, j=0; i>=0; i--, j++){ 1.498 - if (bit[i] == '1') { 1.499 - ret.add(targetVals[j]); 1.500 + // Create src code and corresponding JavaFileObjects. 1.501 + private Iterable<? extends JavaFileObject> getFileList(String className, 1.502 + TestCase testCase, boolean shouldCompile) { 1.503 + Set<ElementType> baseAnnoTarget = testCase.getBaseAnnotations(); 1.504 + Set<ElementType> conAnnoTarget = testCase.getContainerAnnotations(); 1.505 + String srcContent = ""; 1.506 + String pkgInfoContent = ""; 1.507 + String template = Helper.template; 1.508 + String baseTarget = "", conTarget = ""; 1.509 + 1.510 + String target = Helper.ContentVars.TARGET.getVal(); 1.511 + if (baseAnnoTarget != null) { 1.512 + String tmp = target.replace("#VAL", convertToString(baseAnnoTarget).toString()); 1.513 + baseTarget = tmp.replace("[", "{").replace("]", "}"); 1.514 + } 1.515 + if (conAnnoTarget != null) { 1.516 + String tmp = target.replace("#VAL", convertToString(conAnnoTarget).toString()); 1.517 + conTarget = tmp.replace("[", "{").replace("]", "}"); 1.518 + } 1.519 + 1.520 + String annoData = Helper.ContentVars.IMPORTSTMTS.getVal() 1.521 + + conTarget 1.522 + + Helper.ContentVars.CONTAINER.getVal() 1.523 + + baseTarget 1.524 + + Helper.ContentVars.REPEATABLE.getVal() 1.525 + + Helper.ContentVars.BASE.getVal(); 1.526 + 1.527 + JavaFileObject pkgInfoFile = null; 1.528 + 1.529 + // If shouldCompile = true and no @Target is specified for container annotation, 1.530 + // then all 8 ElementType enum constants are applicable as targets for 1.531 + // container annotation. 1.532 + if (shouldCompile && conAnnoTarget == null) { 1.533 + Set<ElementType> copySet = EnumSet.noneOf(ElementType.class); 1.534 + copySet.addAll(jdk7); 1.535 + conAnnoTarget = copySet; 1.536 + } 1.537 + 1.538 + if (shouldCompile) { 1.539 + boolean isPkgCasePresent = conAnnoTarget.contains(PACKAGE); 1.540 + String repeatableAnno = Helper.ContentVars.BASEANNO.getVal() 1.541 + + " " + Helper.ContentVars.BASEANNO.getVal(); 1.542 + for (ElementType s : conAnnoTarget) { 1.543 + String replaceStr = "/*" + s.name() + "*/"; 1.544 + if (s.name().equalsIgnoreCase("PACKAGE")) { 1.545 + //Create packageInfo file. 1.546 + String pkgInfoName = TESTPKG + "." + "package-info"; 1.547 + pkgInfoContent = repeatableAnno + "\npackage " + TESTPKG + ";" + annoData; 1.548 + pkgInfoFile = Helper.getFile(pkgInfoName, pkgInfoContent); 1.549 + } else { 1.550 + template = template.replace(replaceStr, repeatableAnno); 1.551 + if (!isPkgCasePresent) { 1.552 + srcContent = template.replace( 1.553 + "/*ANNODATA*/", annoData).replace("#ClassName", className); 1.554 + } else { 1.555 + replaceStr = "/*PACKAGE*/"; 1.556 + String tmp = template.replace(replaceStr, "package " + TESTPKG + ";"); 1.557 + srcContent = tmp.replace("#ClassName", className); 1.558 + } 1.559 + } 1.560 } 1.561 + } else { 1.562 + // For invalid cases, compilation should fail at declaration site. 1.563 + template = "class #ClassName {}"; 1.564 + srcContent = annoData + template.replace("#ClassName", className); 1.565 } 1.566 - return ret; 1.567 + JavaFileObject srcFile = Helper.getFile(className, srcContent); 1.568 + Iterable<? extends JavaFileObject> files = null; 1.569 + if (pkgInfoFile != null) { 1.570 + files = Arrays.asList(pkgInfoFile, srcFile); 1.571 + } else { 1.572 + files = Arrays.asList(srcFile); 1.573 + } 1.574 + return files; 1.575 } 1.576 1.577 - // Compile the test source file(s) and return test result 1.578 + // Compile the test source file(s) and return test result. 1.579 private boolean getCompileResult(String className, boolean shouldCompile, 1.580 Iterable<? extends JavaFileObject> files) { 1.581 1.582 DiagnosticCollector<JavaFileObject> diagnostics = 1.583 new DiagnosticCollector<JavaFileObject>(); 1.584 Helper.compileCode(diagnostics, files); 1.585 - 1.586 - // Test case pass or fail 1.587 + // Test case pass or fail. 1.588 boolean ok = false; 1.589 - 1.590 String errMesg = ""; 1.591 int numDiags = diagnostics.getDiagnostics().size(); 1.592 - 1.593 if (numDiags == 0) { 1.594 if (shouldCompile) { 1.595 debugPrint("Test passed, compiled as expected."); 1.596 @@ -270,201 +429,80 @@ 1.597 } 1.598 } else { 1.599 if (shouldCompile) { 1.600 - // did not compile 1.601 + // did not compile. 1.602 errMesg = "Test failed, did not compile."; 1.603 ok = false; 1.604 } else { 1.605 - // Error in compilation as expected 1.606 - String expectedErrKey = "compiler.err.invalid.repeatable." + 1.607 - "annotation.incompatible.target"; 1.608 + // Error in compilation as expected. 1.609 + String expectedErrKey = "compiler.err.invalid.repeatable." 1.610 + + "annotation.incompatible.target"; 1.611 for (Diagnostic<?> d : diagnostics.getDiagnostics()) { 1.612 - if((d.getKind() == Diagnostic.Kind.ERROR) && 1.613 - d.getCode().contains(expectedErrKey)) { 1.614 - // Error message as expected 1.615 + if ((d.getKind() == Diagnostic.Kind.ERROR) 1.616 + && d.getCode().contains(expectedErrKey)) { 1.617 + // Error message as expected. 1.618 debugPrint("Error message as expected."); 1.619 ok = true; 1.620 break; 1.621 } else { 1.622 - // error message is incorrect 1.623 + // error message is incorrect. 1.624 ok = false; 1.625 } 1.626 } 1.627 if (!ok) { 1.628 - errMesg = "Incorrect error received when compiling " + 1.629 - className + ", expected: " + expectedErrKey; 1.630 + errMesg = "Incorrect error received when compiling " 1.631 + + className + ", expected: " + expectedErrKey; 1.632 } 1.633 } 1.634 } 1.635 1.636 - if(!ok) { 1.637 + if (!ok) { 1.638 error(errMesg); 1.639 - for (Diagnostic<?> d : diagnostics.getDiagnostics()) 1.640 + for (Diagnostic<?> d : diagnostics.getDiagnostics()) { 1.641 System.out.println(" Diags: " + d); 1.642 + } 1.643 } 1.644 return ok; 1.645 } 1.646 1.647 - private void debugPrint(String string) { 1.648 - if(DEBUG) 1.649 - System.out.println(string); 1.650 + private Set<ElementType> less(Set<ElementType> base, ElementType... sub) { 1.651 + Set<ElementType> res = EnumSet.noneOf(ElementType.class); 1.652 + res.addAll(base); 1.653 + for (ElementType t : sub) { 1.654 + res.remove(t); 1.655 + } 1.656 + return res; 1.657 } 1.658 1.659 - // Create src code and corresponding JavaFileObjects 1.660 - private Iterable<? extends JavaFileObject> getFileList(String className, 1.661 - Set<String> baseAnnoTarget, Set<String> conAnnoTarget, 1.662 - boolean shouldCompile) { 1.663 - 1.664 - String srcContent = ""; 1.665 - String pkgInfoContent = ""; 1.666 - String template = Helper.template; 1.667 - String baseTarget = "", conTarget = ""; 1.668 - 1.669 - String target = Helper.ContentVars.TARGET.getVal(); 1.670 - if(baseAnnoTarget != null) { 1.671 - baseTarget = target.replace("#VAL", baseAnnoTarget.toString()) 1.672 - .replace("[", "{").replace("]", "}"); 1.673 + private Set<ElementType> plus(Set<ElementType> base, ElementType... add) { 1.674 + Set<ElementType> res = EnumSet.noneOf(ElementType.class); 1.675 + res.addAll(base); 1.676 + for (ElementType t : add) { 1.677 + res.add(t); 1.678 } 1.679 - if(conAnnoTarget != null) { 1.680 - conTarget = target.replace("#VAL", conAnnoTarget.toString()) 1.681 - .replace("[", "{").replace("]", "}"); 1.682 - } 1.683 - 1.684 - String annoData = Helper.ContentVars.IMPORTSTMTS.getVal() + 1.685 - conTarget + 1.686 - Helper.ContentVars.CONTAINER.getVal() + 1.687 - baseTarget + 1.688 - Helper.ContentVars.REPEATABLE.getVal() + 1.689 - Helper.ContentVars.BASE.getVal(); 1.690 - 1.691 - JavaFileObject pkgInfoFile = null; 1.692 - 1.693 - /* 1.694 - * If shouldCompile = true and no @Target is specified for container annotation, 1.695 - * then all 8 ElementType enum constants are applicable as targets for 1.696 - * container annotation. 1.697 - */ 1.698 - if(shouldCompile && conAnnoTarget == null) { 1.699 - //conAnnoTarget = new HashSet<String>(Arrays.asList(targetVals)); 1.700 - conAnnoTarget = getDefaultTargetSet(); 1.701 - } 1.702 - 1.703 - if(shouldCompile) { 1.704 - boolean isPkgCasePresent = new ArrayList<String>(conAnnoTarget).contains("ElementType.PACKAGE"); 1.705 - String repeatableAnno = Helper.ContentVars.BASEANNO.getVal() + " " + Helper.ContentVars.BASEANNO.getVal(); 1.706 - for(String s: conAnnoTarget) { 1.707 - s = s.replace("ElementType.",""); 1.708 - String replaceStr = "/*"+s+"*/"; 1.709 - if(s.equalsIgnoreCase("PACKAGE")) { 1.710 - //Create packageInfo file 1.711 - String pkgInfoName = TESTPKG + "." + "package-info"; 1.712 - pkgInfoContent = repeatableAnno + "\npackage " + TESTPKG + ";" + annoData; 1.713 - pkgInfoFile = Helper.getFile(pkgInfoName, pkgInfoContent); 1.714 - } else { 1.715 - template = template.replace(replaceStr, repeatableAnno); 1.716 - //srcContent = template.replace("#ClassName",className); 1.717 - if(!isPkgCasePresent) { 1.718 - srcContent = template.replace("/*ANNODATA*/", annoData).replace("#ClassName",className); 1.719 - } else { 1.720 - replaceStr = "/*PACKAGE*/"; 1.721 - srcContent = template.replace(replaceStr, "package " + TESTPKG + ";") 1.722 - .replace("#ClassName", className); 1.723 - } 1.724 - } 1.725 - } 1.726 - } else { 1.727 - // For invalid cases, compilation should fail at declaration site 1.728 - template = "class #ClassName {}"; 1.729 - srcContent = annoData + template.replace("#ClassName",className); 1.730 - } 1.731 - JavaFileObject srcFile = Helper.getFile(className, srcContent); 1.732 - Iterable<? extends JavaFileObject> files = null; 1.733 - if(pkgInfoFile != null) 1.734 - files = Arrays.asList(pkgInfoFile,srcFile); 1.735 - else 1.736 - files = Arrays.asList(srcFile); 1.737 - return files; 1.738 + return res; 1.739 } 1.740 1.741 - private Set<String> getDefaultTargetSet() { 1.742 - Set<String> defaultSet = new HashSet<>(); 1.743 - int ctr = 0; 1.744 - for(String s : targetVals) { 1.745 - if(ctr++ < DEFAULT_TARGET_CNT) { 1.746 - defaultSet.add(s); 1.747 - } 1.748 + // Iterate target set and add "ElementType." in front of every target type. 1.749 + private List<String> convertToString(Set<ElementType> annoTarget) { 1.750 + if (annoTarget == null) { 1.751 + return null; 1.752 } 1.753 - return defaultSet; 1.754 + List<String> annoTargets = new ArrayList<String>(); 1.755 + for (ElementType e : annoTarget) { 1.756 + annoTargets.add("ElementType." + e.name()); 1.757 + } 1.758 + return annoTargets; 1.759 } 1.760 1.761 - private boolean isValidSubSet(Set<String> baseAnnoTarget, Set<String> conAnnoTarget) { 1.762 - /* 1.763 - * RULE 1: conAnnoTarget should be a subset of baseAnnoTarget 1.764 - * RULE 2: For empty @Target ({}) - annotation cannot be applied anywhere 1.765 - * - Empty sets for both is valid 1.766 - * - Empty baseTarget set is invalid with non-empty conTarget set 1.767 - * - Non-empty baseTarget set is valid with empty conTarget set 1.768 - * RULE 3: For no @Target specified - annotation can be applied to any JDK 7 targets 1.769 - * - No @Target for both is valid 1.770 - * - No @Target for baseTarget set with @Target conTarget set is valid 1.771 - * - @Target for baseTarget set with no @Target for conTarget is invalid 1.772 - */ 1.773 - 1.774 - 1.775 - /* If baseAnno has no @Target, Foo can be either applied to @Target specified for container annotation 1.776 - * else will be applicable for all default targets if no @Target is present for container annotation. 1.777 - * In both cases, the set will be a valid set with no @Target for base annotation 1.778 - */ 1.779 - if(baseAnnoTarget == null) { 1.780 - if(conAnnoTarget == null) return true; 1.781 - return !(conAnnoTarget.contains("ElementType.TYPE_USE") || conAnnoTarget.contains("ElementType.TYPE_PARAMETER")); 1.782 + private void debugPrint(String string) { 1.783 + if (DEBUG) { 1.784 + System.out.println(string); 1.785 } 1.786 - 1.787 - Set<String> tempBaseSet = new HashSet<>(baseAnnoTarget); 1.788 - // If BaseAnno has TYPE, then ANNOTATION_TYPE is allowed by default 1.789 - if(baseAnnoTarget.contains("ElementType.TYPE")) { 1.790 - tempBaseSet.add("ElementType.ANNOTATION_TYPE"); 1.791 - } 1.792 - 1.793 - /* 1.794 - * If containerAnno has no @Target, only valid case if baseAnnoTarget has all targets defined 1.795 - * else invalid set 1.796 - */ 1.797 - if(conAnnoTarget == null) { 1.798 - return (tempBaseSet.containsAll(getDefaultTargetSet())); 1.799 - } 1.800 - 1.801 - // At this point, neither conAnnoTarget or baseAnnoTarget are null 1.802 - if(conAnnoTarget.size() == 0) return true; 1.803 - 1.804 - // At this point, conAnnoTarget is non-empty 1.805 - if (baseAnnoTarget.size() == 0) return false; 1.806 - 1.807 - // At this point, neither conAnnoTarget or baseAnnoTarget are empty 1.808 - return tempBaseSet.containsAll(conAnnoTarget); 1.809 } 1.810 1.811 - void error(String msg) { 1.812 + private void error(String msg) { 1.813 System.out.println("ERROR: " + msg); 1.814 errors++; 1.815 } 1.816 +} 1.817 1.818 - // Lists the start and end range for the given set of target vals 1.819 - void showGroups() { 1.820 - //Group 1: All target set combinations ( 0 to 1048575 ) including empty @Target sets => @Target({}) 1.821 - int grpEnd1 = (int)Math.pow(2, 2*targetVals.length) - 1; 1.822 - System.out.println("[Group 1]: 0 - " + grpEnd1); 1.823 - 1.824 - //Group 2: @Target not defined for base annotation ( 1048576 - 1049599 ). 1.825 - System.out.print("[Group 2]: " + (grpEnd1 + 1) + " - "); 1.826 - int grpEnd2 = grpEnd1 + 1 + (int)Math.pow(2, targetVals.length) - 1; 1.827 - System.out.println(grpEnd2); 1.828 - 1.829 - //Group 3: @Target not defined for container annotation ( 1049600 - 1050623 ). 1.830 - System.out.print("[Group 3]: " + (grpEnd2 + 1) + " - "); 1.831 - int grpEnd3 = grpEnd2 + 1 + (int)Math.pow(2, targetVals.length) - 1; 1.832 - System.out.println(grpEnd3); 1.833 - 1.834 - //Group 4: @Target not defined for both base and container annotations ( 1050624 ). 1.835 - System.out.println("[Group 4]: " + (grpEnd3 + 1)); 1.836 - } 1.837 -}