test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java

Mon, 18 Feb 2013 14:29:40 -0800

author
jjg
date
Mon, 18 Feb 2013 14:29:40 -0800
changeset 1589
87884cd0fea3
parent 1554
5125b9854d07
child 1641
195b71850b56
permissions
-rw-r--r--

8008339: Test TargetAnnoCombo.java is broken
Reviewed-by: jjh

darcy@1554 1 /*
darcy@1554 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
darcy@1554 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
darcy@1554 4 *
darcy@1554 5 * This code is free software; you can redistribute it and/or modify it
darcy@1554 6 * under the terms of the GNU General Public License version 2 only, as
darcy@1554 7 * published by the Free Software Foundation.
darcy@1554 8 *
darcy@1554 9 * This code is distributed in the hope that it will be useful, but WITHOUT
darcy@1554 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
darcy@1554 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
darcy@1554 12 * version 2 for more details (a copy is included in the LICENSE file that
darcy@1554 13 * accompanied this code).
darcy@1554 14 *
darcy@1554 15 * You should have received a copy of the GNU General Public License version
darcy@1554 16 * 2 along with this work; if not, write to the Free Software Foundation,
darcy@1554 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
darcy@1554 18 *
darcy@1554 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
darcy@1554 20 * or visit www.oracle.com if you need additional information or have any
darcy@1554 21 * questions.
darcy@1554 22 */
darcy@1554 23
darcy@1554 24 /**
darcy@1554 25 * @test
darcy@1554 26 * @bug 7195131
darcy@1554 27 * @author sogoel
darcy@1554 28 * @summary Combo test for all possible combinations for Target values
jjg@1589 29 * @ignore 8008339 Test TargetAnnoCombo.java is broken
darcy@1554 30 * @build Helper
darcy@1554 31 * @compile TargetAnnoCombo.java TestCaseGenerator.java
darcy@1554 32 * @run main TargetAnnoCombo
darcy@1554 33 */
darcy@1554 34
darcy@1554 35 import java.io.IOException;
darcy@1554 36 import java.util.ArrayList;
darcy@1554 37 import java.util.Arrays;
darcy@1554 38 import java.util.HashSet;
darcy@1554 39 import java.util.Set;
darcy@1554 40 import javax.tools.Diagnostic;
darcy@1554 41 import javax.tools.DiagnosticCollector;
darcy@1554 42 import javax.tools.JavaFileObject;
darcy@1554 43
darcy@1554 44 /*
darcy@1554 45 * TargetAnnoCombo gets a list of test case numbers using TestCaseGenerator.
darcy@1554 46 * For each of the test case number, @Target sets for base and container annotations
darcy@1554 47 * are determined, source files are generated, compiled, and the result is verified
darcy@1554 48 * based on if the @Target set for base and container is a positive or negative combination.
darcy@1554 49 *
darcy@1554 50 * @Target sets for base and container annotations are determined using a bit mapping of
darcy@1554 51 * 10 ElementType enum constants defined in JDK8.
darcy@1554 52 *
darcy@1554 53 * Bit Target value
darcy@1554 54 * 0 "ElementType.ANNOTATION_TYPE"
darcy@1554 55 * 1 "ElementType.CONSTRUCTOR"
darcy@1554 56 * 2 "ElementType.FIELD"
darcy@1554 57 * 3 "ElementType.LOCAL_VARIABLE"
darcy@1554 58 * 4 "ElementType.METHOD"
darcy@1554 59 * 5 "ElementType.TYPE"
darcy@1554 60 * 6 "ElementType.PARAMETER"
darcy@1554 61 * 7 "ElementType.PACKAGE"
darcy@1554 62 * 8 "ElementType.TYPE_USE"
darcy@1554 63 * 9 "ElementType.TYPE_PARAMETER"
darcy@1554 64 *
darcy@1554 65 * Group 1:
darcy@1554 66 * 20 bits mapping, representing a test case number, is used for all target set
darcy@1554 67 * combinations ( 0 to 1048575 ) including empty @Target sets => @Target({}).
darcy@1554 68 * From this 20 bits, 10 bits are for base followed by 10 bits for container
darcy@1554 69 * where each bit maps to an ElementType enum constant defined in JDK8.
darcy@1554 70 *
darcy@1554 71 * Examples:
darcy@1554 72 * Test case number: 4, binary: 100 => container=100, base=[], container=["ElementType.FIELD"]
darcy@1554 73 * Test case number: 1003575, binary: 11110101000000110111 => base=1111010100, container=0000110111;
darcy@1554 74 * base=["ElementType.PARAMETER", "ElementType.TYPE_USE", "ElementType.METHOD", "ElementType.FIELD", "ElementType.PACKAGE", "ElementType.TYPE_PARAMETER"],
darcy@1554 75 * container=["ElementType.TYPE", "ElementType.METHOD", "ElementType.ANNOTATION_TYPE", "ElementType.CONSTRUCTOR", "ElementType.FIELD"]
darcy@1554 76 *
darcy@1554 77 * In the following groups, no @Target set is represented by null.
darcy@1554 78 * Group 2:
darcy@1554 79 * @Target is not defined on base.
darcy@1554 80 * Target sets for container are determined using the 10-bit binary number
darcy@1554 81 * resulting in 1024 test cases, mapping them to test case numbers from
darcy@1554 82 * 1048576 to (1048576 + 1023) => 1048576 to 1049599.
darcy@1554 83 *
darcy@1554 84 * Example:
darcy@1554 85 * Test case number: 1048587 => 1048587 - 1048576 = test case 11 in Group 2, binary: 1011 =>
darcy@1554 86 * base = null,
darcy@1554 87 * container = ["ElementType.ANNOTATION_TYPE","ElementType.CONSTRUCTOR","ElementType.LOCAL_VARIABLE"]
darcy@1554 88 *
darcy@1554 89 * Group 3:
darcy@1554 90 * @Target is not defined on container
darcy@1554 91 * Target sets for base are determined using the 10-bit binary number
darcy@1554 92 * resulting in 1024 test cases, mapping them to test case numbers from
darcy@1554 93 * 1049600 to (1049600 + 1023) => 1049600 to 1050623.
darcy@1554 94 *
darcy@1554 95 * Example:
darcy@1554 96 * Test case number: 1049708 => 1049708 - 1049600 = test case 108 in Group 3, binary: 1101100 =>
darcy@1554 97 * base = ["ElementType.FIELD", "ElementType.LOCAL_VARIABLE", "ElementType.TYPE", "ElementType.PARAMETER"],
darcy@1554 98 * container = null
darcy@1554 99 *
darcy@1554 100 * For the above group, test case number: 1049855 gives compiler error, JDK-8006547 filed
darcy@1554 101 *
darcy@1554 102 * Group 4:
darcy@1554 103 * @Target not defined for both base and container annotations.
darcy@1554 104 *
darcy@1554 105 * This is the last test and corresponds to test case number 1050624. base=null, container=null
darcy@1554 106 *
darcy@1554 107 * Examples to run this test:
darcy@1554 108 * 1. Run a specific test case number:
darcy@1554 109 * ${JTREG} -DTestCaseNum=10782 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
darcy@1554 110 * 2. Run specific number of tests:
darcy@1554 111 * ${JTREG} -DNumberOfTests=4 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
darcy@1554 112 * 3. Run specific number of tests with a seed:
darcy@1554 113 * ${JTREG} -DNumberOfTests=4 -DTestSeed=-972894659 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
darcy@1554 114 * 4. Run tests in default mode (number of tests = 1000):
darcy@1554 115 * ${JTREG} -DTestMode=DEFAULT -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
darcy@1554 116 * 5. Run all tests (FULL mode):
darcy@1554 117 * ${JTREG} -DTestMode=FULL -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
darcy@1554 118 *
darcy@1554 119 */
darcy@1554 120
darcy@1554 121 public class TargetAnnoCombo {
darcy@1554 122 int errors = 0;
darcy@1554 123 static final String TESTPKG = "testpkg";
darcy@1554 124 /*
darcy@1554 125 * Set it to true to get more debug information including base and
darcy@1554 126 * container target sets for a given test case number
darcy@1554 127 */
darcy@1554 128 static final boolean DEBUG = false;
darcy@1554 129
darcy@1554 130 // JDK 5/6/7/8 Targets
darcy@1554 131 static final String[] targetVals = {"ElementType.ANNOTATION_TYPE",
darcy@1554 132 "ElementType.CONSTRUCTOR", "ElementType.FIELD",
darcy@1554 133 "ElementType.LOCAL_VARIABLE", "ElementType.METHOD",
darcy@1554 134 "ElementType.TYPE", "ElementType.PARAMETER",
darcy@1554 135 "ElementType.PACKAGE", "ElementType.TYPE_USE",
darcy@1554 136 "ElementType.TYPE_PARAMETER"};
darcy@1554 137
darcy@1554 138 // TYPE_USE and TYPE_PARAMETER (added in JDK8) are not part of default Target set
darcy@1554 139 static final int DEFAULT_TARGET_CNT = 8;
darcy@1554 140
darcy@1554 141 public static void main(String args[]) throws Exception {
darcy@1554 142
darcy@1554 143 /* maxTestNum = (base and container combinations of targetVals elems [0 - 1048575 combos])
darcy@1554 144 * + (combinations where base or container has no Target [1024 combos])
darcy@1554 145 * + (no -1 even though 1st test is number 0 as last test is where both
darcy@1554 146 * base and container have no target)
darcy@1554 147 */
darcy@1554 148
darcy@1554 149 int maxTestNum = (int)Math.pow(2, 2*targetVals.length) + 2*(int)Math.pow(2, targetVals.length);
darcy@1554 150 TestCaseGenerator tcg = new TestCaseGenerator(maxTestNum);
darcy@1554 151 TargetAnnoCombo tac = new TargetAnnoCombo();
darcy@1554 152
darcy@1554 153 int testCtr = 0;
darcy@1554 154 int testCase = -1;
darcy@1554 155 while ( (testCase=tcg.getNextTestCase()) != -1 ) {
darcy@1554 156 tac.executeTestCase(testCase, maxTestNum);
darcy@1554 157 testCtr++;
darcy@1554 158 }
darcy@1554 159
darcy@1554 160 System.out.println("Total tests run: " + testCtr);
darcy@1554 161 if (tac.errors > 0)
darcy@1554 162 throw new Exception(tac.errors + " errors found");
darcy@1554 163 }
darcy@1554 164
darcy@1554 165 /*
darcy@1554 166 * For given testCase, determine the base and container annotation Target sets,
darcy@1554 167 * get if testCase should compile, get test source file(s), get compilation result and verify.
darcy@1554 168 *
darcy@1554 169 */
darcy@1554 170 private void executeTestCase(int testCase, int maxTestNum) {
darcy@1554 171
darcy@1554 172 // Determine base and container annotation Target sets for the testCase
darcy@1554 173 Set<String> baseAnnoTarget = null;
darcy@1554 174 Set<String> conAnnoTarget = null;
darcy@1554 175
darcy@1554 176 //Number of base and container combinations [0 - 1048575 combos]
darcy@1554 177 int baseContCombos = (int)Math.pow(2, 2*targetVals.length);
darcy@1554 178 //Number of either base or container combinations when one of them has no @Target [1024 combos]
darcy@1554 179 int targetValsCombos = (int)Math.pow(2, targetVals.length);
darcy@1554 180
darcy@1554 181 if (testCase >= baseContCombos) {
darcy@1554 182 //Base annotation do not have @Target
darcy@1554 183 if (testCase < baseContCombos + targetValsCombos) {
darcy@1554 184 baseAnnoTarget = null;
darcy@1554 185 conAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos));
darcy@1554 186 } else if (testCase < baseContCombos + 2*targetValsCombos) {
darcy@1554 187 //Container annotation do not have @Target
darcy@1554 188 baseAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos - targetValsCombos));
darcy@1554 189 conAnnoTarget = null;
darcy@1554 190 } else {
darcy@1554 191 //Both Base and Container annotation do not have @Target
darcy@1554 192 baseAnnoTarget = null;
darcy@1554 193 conAnnoTarget = null;
darcy@1554 194 }
darcy@1554 195 } else {
darcy@1554 196 //TestCase number is represented as 10-bits for base followed by container bits
darcy@1554 197 String bin = Integer.toBinaryString(testCase);
darcy@1554 198 String base="", cont=bin;
darcy@1554 199 if (bin.length() > targetVals.length){
darcy@1554 200 base = bin.substring(0, bin.length() - targetVals.length);
darcy@1554 201 cont = bin.substring(bin.length() - targetVals.length,bin.length());
darcy@1554 202 }
darcy@1554 203 baseAnnoTarget = getSetFromBitVec(base);
darcy@1554 204 conAnnoTarget = getSetFromBitVec(cont);
darcy@1554 205 }
darcy@1554 206
darcy@1554 207 debugPrint("Test case number = " + testCase + " => binary = " + Integer.toBinaryString(testCase));
darcy@1554 208 debugPrint(" => baseAnnoTarget = " + baseAnnoTarget);
darcy@1554 209 debugPrint(" => containerAnnoTarget = " + conAnnoTarget);
darcy@1554 210
darcy@1554 211 // Determine if a testCase should compile or not
darcy@1554 212 String className = "TC" + testCase;
darcy@1554 213 boolean shouldCompile = isValidSubSet(baseAnnoTarget, conAnnoTarget);
darcy@1554 214
darcy@1554 215 // Get test source file(s)
darcy@1554 216 Iterable<? extends JavaFileObject> files = getFileList(className, baseAnnoTarget,
darcy@1554 217 conAnnoTarget, shouldCompile);
darcy@1554 218
darcy@1554 219 // Get result of compiling test src file(s)
darcy@1554 220 boolean result = getCompileResult(className, shouldCompile, files);
darcy@1554 221
darcy@1554 222 // List test src code if test fails
darcy@1554 223 if(!result) {
darcy@1554 224 System.out.println("FAIL: Test " + testCase);
darcy@1554 225 try {
darcy@1554 226 for (JavaFileObject f: files) {
darcy@1554 227 System.out.println("File: " + f.getName() + "\n" + f.getCharContent(true));
darcy@1554 228 }
darcy@1554 229 } catch (IOException ioe) {
darcy@1554 230 System.out.println("Exception: " + ioe);
darcy@1554 231 }
darcy@1554 232 } else {
darcy@1554 233 debugPrint("PASS: Test " + testCase);
darcy@1554 234 }
darcy@1554 235 }
darcy@1554 236
darcy@1554 237 // Get a Set<String> based on bits that are set to 1
darcy@1554 238 public Set<String> getSetFromBitVec(String bitVec) {
darcy@1554 239 Set<String> ret = new HashSet<>();
darcy@1554 240 char[] bit = bitVec.toCharArray();
darcy@1554 241 for (int i=bit.length-1, j=0; i>=0; i--, j++){
darcy@1554 242 if (bit[i] == '1') {
darcy@1554 243 ret.add(targetVals[j]);
darcy@1554 244 }
darcy@1554 245 }
darcy@1554 246 return ret;
darcy@1554 247 }
darcy@1554 248
darcy@1554 249 // Compile the test source file(s) and return test result
darcy@1554 250 private boolean getCompileResult(String className, boolean shouldCompile,
darcy@1554 251 Iterable<? extends JavaFileObject> files) {
darcy@1554 252
darcy@1554 253 DiagnosticCollector<JavaFileObject> diagnostics =
darcy@1554 254 new DiagnosticCollector<JavaFileObject>();
darcy@1554 255 Helper.compileCode(diagnostics, files);
darcy@1554 256
darcy@1554 257 // Test case pass or fail
darcy@1554 258 boolean ok = false;
darcy@1554 259
darcy@1554 260 String errMesg = "";
darcy@1554 261 int numDiags = diagnostics.getDiagnostics().size();
darcy@1554 262
darcy@1554 263 if (numDiags == 0) {
darcy@1554 264 if (shouldCompile) {
darcy@1554 265 debugPrint("Test passed, compiled as expected.");
darcy@1554 266 ok = true;
darcy@1554 267 } else {
darcy@1554 268 errMesg = "Test failed, compiled unexpectedly.";
darcy@1554 269 ok = false;
darcy@1554 270 }
darcy@1554 271 } else {
darcy@1554 272 if (shouldCompile) {
darcy@1554 273 // did not compile
darcy@1554 274 errMesg = "Test failed, did not compile.";
darcy@1554 275 ok = false;
darcy@1554 276 } else {
darcy@1554 277 // Error in compilation as expected
darcy@1554 278 String expectedErrKey = "compiler.err.invalid.repeatable." +
darcy@1554 279 "annotation.incompatible.target";
darcy@1554 280 for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
darcy@1554 281 if((d.getKind() == Diagnostic.Kind.ERROR) &&
darcy@1554 282 d.getCode().contains(expectedErrKey)) {
darcy@1554 283 // Error message as expected
darcy@1554 284 debugPrint("Error message as expected.");
darcy@1554 285 ok = true;
darcy@1554 286 break;
darcy@1554 287 } else {
darcy@1554 288 // error message is incorrect
darcy@1554 289 ok = false;
darcy@1554 290 }
darcy@1554 291 }
darcy@1554 292 if (!ok) {
darcy@1554 293 errMesg = "Incorrect error received when compiling " +
darcy@1554 294 className + ", expected: " + expectedErrKey;
darcy@1554 295 }
darcy@1554 296 }
darcy@1554 297 }
darcy@1554 298
darcy@1554 299 if(!ok) {
darcy@1554 300 error(errMesg);
darcy@1554 301 for (Diagnostic<?> d : diagnostics.getDiagnostics())
darcy@1554 302 System.out.println(" Diags: " + d);
darcy@1554 303 }
darcy@1554 304 return ok;
darcy@1554 305 }
darcy@1554 306
darcy@1554 307 private void debugPrint(String string) {
darcy@1554 308 if(DEBUG)
darcy@1554 309 System.out.println(string);
darcy@1554 310 }
darcy@1554 311
darcy@1554 312 // Create src code and corresponding JavaFileObjects
darcy@1554 313 private Iterable<? extends JavaFileObject> getFileList(String className,
darcy@1554 314 Set<String> baseAnnoTarget, Set<String> conAnnoTarget,
darcy@1554 315 boolean shouldCompile) {
darcy@1554 316
darcy@1554 317 String srcContent = "";
darcy@1554 318 String pkgInfoContent = "";
darcy@1554 319 String template = Helper.template;
darcy@1554 320 String baseTarget = "", conTarget = "";
darcy@1554 321
darcy@1554 322 String target = Helper.ContentVars.TARGET.getVal();
darcy@1554 323 if(baseAnnoTarget != null) {
darcy@1554 324 baseTarget = target.replace("#VAL", baseAnnoTarget.toString())
darcy@1554 325 .replace("[", "{").replace("]", "}");
darcy@1554 326 }
darcy@1554 327 if(conAnnoTarget != null) {
darcy@1554 328 conTarget = target.replace("#VAL", conAnnoTarget.toString())
darcy@1554 329 .replace("[", "{").replace("]", "}");
darcy@1554 330 }
darcy@1554 331
darcy@1554 332 String annoData = Helper.ContentVars.IMPORTSTMTS.getVal() +
darcy@1554 333 conTarget +
darcy@1554 334 Helper.ContentVars.CONTAINER.getVal() +
darcy@1554 335 baseTarget +
darcy@1554 336 Helper.ContentVars.REPEATABLE.getVal() +
darcy@1554 337 Helper.ContentVars.BASE.getVal();
darcy@1554 338
darcy@1554 339 JavaFileObject pkgInfoFile = null;
darcy@1554 340
darcy@1554 341 /*
darcy@1554 342 * If shouldCompile = true and no @Target is specified for container annotation,
darcy@1554 343 * then all 8 ElementType enum constants are applicable as targets for
darcy@1554 344 * container annotation.
darcy@1554 345 */
darcy@1554 346 if(shouldCompile && conAnnoTarget == null) {
darcy@1554 347 //conAnnoTarget = new HashSet<String>(Arrays.asList(targetVals));
darcy@1554 348 conAnnoTarget = getDefaultTargetSet();
darcy@1554 349 }
darcy@1554 350
darcy@1554 351 if(shouldCompile) {
darcy@1554 352 boolean isPkgCasePresent = new ArrayList<String>(conAnnoTarget).contains("ElementType.PACKAGE");
darcy@1554 353 String repeatableAnno = Helper.ContentVars.BASEANNO.getVal() + " " + Helper.ContentVars.BASEANNO.getVal();
darcy@1554 354 for(String s: conAnnoTarget) {
darcy@1554 355 s = s.replace("ElementType.","");
darcy@1554 356 String replaceStr = "/*"+s+"*/";
darcy@1554 357 if(s.equalsIgnoreCase("PACKAGE")) {
darcy@1554 358 //Create packageInfo file
darcy@1554 359 String pkgInfoName = TESTPKG + "." + "package-info";
darcy@1554 360 pkgInfoContent = repeatableAnno + "\npackage " + TESTPKG + ";" + annoData;
darcy@1554 361 pkgInfoFile = Helper.getFile(pkgInfoName, pkgInfoContent);
darcy@1554 362 } else {
darcy@1554 363 template = template.replace(replaceStr, repeatableAnno);
darcy@1554 364 //srcContent = template.replace("#ClassName",className);
darcy@1554 365 if(!isPkgCasePresent) {
darcy@1554 366 srcContent = template.replace("/*ANNODATA*/", annoData).replace("#ClassName",className);
darcy@1554 367 } else {
darcy@1554 368 replaceStr = "/*PACKAGE*/";
darcy@1554 369 srcContent = template.replace(replaceStr, "package " + TESTPKG + ";")
darcy@1554 370 .replace("#ClassName", className);
darcy@1554 371 }
darcy@1554 372 }
darcy@1554 373 }
darcy@1554 374 } else {
darcy@1554 375 // For invalid cases, compilation should fail at declaration site
darcy@1554 376 template = "class #ClassName {}";
darcy@1554 377 srcContent = annoData + template.replace("#ClassName",className);
darcy@1554 378 }
darcy@1554 379 JavaFileObject srcFile = Helper.getFile(className, srcContent);
darcy@1554 380 Iterable<? extends JavaFileObject> files = null;
darcy@1554 381 if(pkgInfoFile != null)
darcy@1554 382 files = Arrays.asList(pkgInfoFile,srcFile);
darcy@1554 383 else
darcy@1554 384 files = Arrays.asList(srcFile);
darcy@1554 385 return files;
darcy@1554 386 }
darcy@1554 387
darcy@1554 388 private Set<String> getDefaultTargetSet() {
darcy@1554 389 Set<String> defaultSet = new HashSet<>();
darcy@1554 390 int ctr = 0;
darcy@1554 391 for(String s : targetVals) {
darcy@1554 392 if(ctr++ < DEFAULT_TARGET_CNT) {
darcy@1554 393 defaultSet.add(s);
darcy@1554 394 }
darcy@1554 395 }
darcy@1554 396 return defaultSet;
darcy@1554 397 }
darcy@1554 398
darcy@1554 399 private boolean isValidSubSet(Set<String> baseAnnoTarget, Set<String> conAnnoTarget) {
darcy@1554 400 /*
darcy@1554 401 * RULE 1: conAnnoTarget should be a subset of baseAnnoTarget
darcy@1554 402 * RULE 2: For empty @Target ({}) - annotation cannot be applied anywhere
darcy@1554 403 * - Empty sets for both is valid
darcy@1554 404 * - Empty baseTarget set is invalid with non-empty conTarget set
darcy@1554 405 * - Non-empty baseTarget set is valid with empty conTarget set
darcy@1554 406 * RULE 3: For no @Target specified - annotation can be applied to any JDK 7 targets
darcy@1554 407 * - No @Target for both is valid
darcy@1554 408 * - No @Target for baseTarget set with @Target conTarget set is valid
darcy@1554 409 * - @Target for baseTarget set with no @Target for conTarget is invalid
darcy@1554 410 */
darcy@1554 411
darcy@1554 412
darcy@1554 413 /* If baseAnno has no @Target, Foo can be either applied to @Target specified for container annotation
darcy@1554 414 * else will be applicable for all default targets if no @Target is present for container annotation.
darcy@1554 415 * In both cases, the set will be a valid set with no @Target for base annotation
darcy@1554 416 */
darcy@1554 417 if(baseAnnoTarget == null) {
darcy@1554 418 if(conAnnoTarget == null) return true;
darcy@1554 419 return !(conAnnoTarget.contains("ElementType.TYPE_USE") || conAnnoTarget.contains("ElementType.TYPE_PARAMETER"));
darcy@1554 420 }
darcy@1554 421
darcy@1554 422 Set<String> tempBaseSet = new HashSet<>(baseAnnoTarget);
darcy@1554 423 // If BaseAnno has TYPE, then ANNOTATION_TYPE is allowed by default
darcy@1554 424 if(baseAnnoTarget.contains("ElementType.TYPE")) {
darcy@1554 425 tempBaseSet.add("ElementType.ANNOTATION_TYPE");
darcy@1554 426 }
darcy@1554 427
darcy@1554 428 /*
darcy@1554 429 * If containerAnno has no @Target, only valid case if baseAnnoTarget has all targets defined
darcy@1554 430 * else invalid set
darcy@1554 431 */
darcy@1554 432 if(conAnnoTarget == null) {
darcy@1554 433 return (tempBaseSet.containsAll(getDefaultTargetSet()));
darcy@1554 434 }
darcy@1554 435
darcy@1554 436 // At this point, neither conAnnoTarget or baseAnnoTarget are null
darcy@1554 437 if(conAnnoTarget.size() == 0) return true;
darcy@1554 438
darcy@1554 439 // At this point, conAnnoTarget is non-empty
darcy@1554 440 if (baseAnnoTarget.size() == 0) return false;
darcy@1554 441
darcy@1554 442 // At this point, neither conAnnoTarget or baseAnnoTarget are empty
darcy@1554 443 return tempBaseSet.containsAll(conAnnoTarget);
darcy@1554 444 }
darcy@1554 445
darcy@1554 446 void error(String msg) {
darcy@1554 447 System.out.println("ERROR: " + msg);
darcy@1554 448 errors++;
darcy@1554 449 }
darcy@1554 450
darcy@1554 451 // Lists the start and end range for the given set of target vals
darcy@1554 452 void showGroups() {
darcy@1554 453 //Group 1: All target set combinations ( 0 to 1048575 ) including empty @Target sets => @Target({})
darcy@1554 454 int grpEnd1 = (int)Math.pow(2, 2*targetVals.length) - 1;
darcy@1554 455 System.out.println("[Group 1]: 0 - " + grpEnd1);
darcy@1554 456
darcy@1554 457 //Group 2: @Target not defined for base annotation ( 1048576 - 1049599 ).
darcy@1554 458 System.out.print("[Group 2]: " + (grpEnd1 + 1) + " - ");
darcy@1554 459 int grpEnd2 = grpEnd1 + 1 + (int)Math.pow(2, targetVals.length) - 1;
darcy@1554 460 System.out.println(grpEnd2);
darcy@1554 461
darcy@1554 462 //Group 3: @Target not defined for container annotation ( 1049600 - 1050623 ).
darcy@1554 463 System.out.print("[Group 3]: " + (grpEnd2 + 1) + " - ");
darcy@1554 464 int grpEnd3 = grpEnd2 + 1 + (int)Math.pow(2, targetVals.length) - 1;
darcy@1554 465 System.out.println(grpEnd3);
darcy@1554 466
darcy@1554 467 //Group 4: @Target not defined for both base and container annotations ( 1050624 ).
darcy@1554 468 System.out.println("[Group 4]: " + (grpEnd3 + 1));
darcy@1554 469 }
darcy@1554 470 }

mercurial