1 /******************************************************************************* 2 * Copyright (c) 2000, 2019 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jdt.core.tests.util; 15 16 import java.io.File; 17 import java.lang.reflect.Constructor; 18 import java.lang.reflect.InvocationTargetException; 19 import java.util.ArrayList; 20 import java.util.HashMap; 21 import java.util.List; 22 import java.util.Map; 23 24 import junit.framework.Test; 25 import junit.framework.TestSuite; 26 27 import org.eclipse.core.runtime.IPath; 28 import org.eclipse.core.runtime.Path; 29 import org.eclipse.jdt.core.tests.compiler.regression.RegressionTestSetup; 30 import org.eclipse.jdt.core.tests.junit.extension.TestCase; 31 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 32 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; 33 34 @SuppressWarnings({ "unchecked", "rawtypes" }) 35 public class AbstractCompilerTest extends TestCase { 36 37 public static final int F_1_3 = 0x01; 38 public static final int F_1_4 = 0x02; 39 public static final int F_1_5 = 0x04; 40 public static final int F_1_6 = 0x08; 41 public static final int F_1_7 = 0x10; 42 public static final int F_1_8 = 0x20; 43 public static final int F_9 = 0x40; 44 public static final int F_10 = 0x80; 45 public static final int F_11 = 0x100; 46 public static final int F_12 = 0x200; 47 public static final int F_13 = 0x400; 48 public static final int F_14 = 0x800; 49 50 public static final boolean RUN_JAVAC = CompilerOptions.ENABLED.equals(System.getProperty("run.javac")); 51 private static final int UNINITIALIZED = -1; 52 private static final int NONE = 0; 53 private static int possibleComplianceLevels = UNINITIALIZED; 54 55 protected long complianceLevel; 56 protected boolean enableAPT = false; 57 protected static boolean isJRE9Plus = false; // Stop gap, so tests need not be run at 9, but some tests can be adjusted for JRE 9 58 protected static boolean isJRE11Plus = false; 59 protected static boolean isJRE12Plus = false; 60 protected static boolean isJRE13Plus = false; 61 protected static boolean isJRE14Plus = false; 62 protected static boolean reflectNestedClassUseDollar; 63 64 /** 65 * Build a test suite made of test suites for all possible running VM compliances . 66 * 67 * @see #buildUniqueComplianceTestSuite(Class, long) for test suite children content. 68 * 69 * @param evaluationTestClass The main test suite to build. 70 * @return built test suite (see {@link TestSuite} 71 */ buildAllCompliancesTestSuite(Class evaluationTestClass)72 public static Test buildAllCompliancesTestSuite(Class evaluationTestClass) { 73 TestSuite suite = new TestSuite(evaluationTestClass.getName()); 74 buildAllCompliancesTestSuite(suite, evaluationTestClass); 75 return suite; 76 } buildAllCompliancesTestSuite(TestSuite suite, Class evaluationTestClass)77 public static void buildAllCompliancesTestSuite(TestSuite suite, Class evaluationTestClass) { 78 int complianceLevels = AbstractCompilerTest.getPossibleComplianceLevels(); 79 if ((complianceLevels & AbstractCompilerTest.F_1_3) != 0) { 80 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_3)); 81 } 82 if ((complianceLevels & AbstractCompilerTest.F_1_4) != 0) { 83 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_4)); 84 } 85 if ((complianceLevels & AbstractCompilerTest.F_1_5) != 0) { 86 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_5)); 87 } 88 if ((complianceLevels & AbstractCompilerTest.F_1_6) != 0) { 89 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_6)); 90 } 91 if ((complianceLevels & AbstractCompilerTest.F_1_7) != 0) { 92 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_7)); 93 } 94 if ((complianceLevels & AbstractCompilerTest.F_1_8) != 0) { 95 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_8)); 96 } 97 if ((complianceLevels & AbstractCompilerTest.F_9) != 0) { 98 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK9)); 99 } 100 if ((complianceLevels & AbstractCompilerTest.F_10) != 0) { 101 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK10)); 102 } 103 if ((complianceLevels & AbstractCompilerTest.F_11) != 0) { 104 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11))); 105 } 106 if ((complianceLevels & AbstractCompilerTest.F_12) != 0) { 107 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12))); 108 } 109 if ((complianceLevels & AbstractCompilerTest.F_13) != 0) { 110 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_13))); 111 } 112 if ((complianceLevels & AbstractCompilerTest.F_14) != 0) { 113 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_14))); 114 } 115 } 116 117 /** 118 * Build a test suite made of test suites for all possible running VM compliances . 119 * 120 * @see #buildComplianceTestSuite(List, Class, long) for test suite children content. 121 * 122 * @param testSuiteClass The main test suite to build. 123 * @param setupClass The compiler setup to class to use to bundle given tets suites tests. 124 * @param testClasses The list of test suites to include in main test suite. 125 * @return built test suite (see {@link TestSuite} 126 */ buildAllCompliancesTestSuite(Class testSuiteClass, Class setupClass, List testClasses)127 public static Test buildAllCompliancesTestSuite(Class testSuiteClass, Class setupClass, List testClasses) { 128 TestSuite suite = new TestSuite(testSuiteClass.getName()); 129 int complianceLevels = AbstractCompilerTest.getPossibleComplianceLevels(); 130 if ((complianceLevels & AbstractCompilerTest.F_1_3) != 0) { 131 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.JDK1_3)); 132 } 133 if ((complianceLevels & AbstractCompilerTest.F_1_4) != 0) { 134 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.JDK1_4)); 135 } 136 if ((complianceLevels & AbstractCompilerTest.F_1_5) != 0) { 137 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.JDK1_5)); 138 } 139 if ((complianceLevels & AbstractCompilerTest.F_1_6) != 0) { 140 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.JDK1_6)); 141 } 142 if ((complianceLevels & AbstractCompilerTest.F_1_7) != 0) { 143 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.JDK1_7)); 144 } 145 if ((complianceLevels & AbstractCompilerTest.F_1_8) != 0) { 146 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.JDK1_8)); 147 } 148 if ((complianceLevels & AbstractCompilerTest.F_9) != 0) { 149 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.JDK9)); 150 } 151 if ((complianceLevels & AbstractCompilerTest.F_10) != 0) { 152 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.JDK10)); 153 } 154 if ((complianceLevels & AbstractCompilerTest.F_11) != 0) { 155 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11))); 156 } 157 if ((complianceLevels & AbstractCompilerTest.F_12) != 0) { 158 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12))); 159 } 160 if ((complianceLevels & AbstractCompilerTest.F_13) != 0) { 161 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_13))); 162 } 163 if ((complianceLevels & AbstractCompilerTest.F_14) != 0) { 164 suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_14))); 165 } 166 return suite; 167 } 168 setpossibleComplianceLevels(int complianceLevel)169 public static void setpossibleComplianceLevels(int complianceLevel) { 170 possibleComplianceLevels = complianceLevel; 171 } 172 173 /** 174 * Build a test suite for a compliance and a list of test suites. 175 * Returned test suite has only one child: {@link RegressionTestSetup} test suite. 176 * Name of returned suite is the given compliance level. 177 * 178 * @see #buildComplianceTestSuite(List, Class, long) for child test suite content. 179 * 180 * @param complianceLevel The compliance level used for this test suite. 181 * @param testClasses The list of test suites to include in main test suite. 182 * @return built test suite (see {@link TestSuite} 183 */ buildComplianceTestSuite(long complianceLevel, List testClasses)184 public static Test buildComplianceTestSuite(long complianceLevel, List testClasses) { 185 return buildComplianceTestSuite(testClasses, RegressionTestSetup.class, complianceLevel); 186 } 187 188 /** 189 * Build a test suite for a compliance and a list of test suites. 190 * Children of returned test suite are setup test suites (see {@link CompilerTestSetup}). 191 * Name of returned suite is the given compliance level. 192 * 193 * @param complianceLevel The compliance level used for this test suite. 194 * @param testClasses The list of test suites to include in main test suite. 195 * @return built test suite (see {@link TestSuite} 196 */ buildComplianceTestSuite(List testClasses, Class setupClass, long complianceLevel)197 private static Test buildComplianceTestSuite(List testClasses, Class setupClass, long complianceLevel) { 198 // call the setup constructor with the compliance level 199 TestSuite complianceSuite = null; 200 try { 201 Constructor constructor = setupClass.getConstructor(new Class[]{long.class}); 202 complianceSuite = (TestSuite)constructor.newInstance(new Object[]{new Long(complianceLevel)}); 203 } catch (IllegalAccessException e) { 204 e.printStackTrace(); 205 } catch (InstantiationException e) { 206 e.printStackTrace(); 207 } catch (InvocationTargetException e) { 208 e.getTargetException().printStackTrace(); 209 } catch (NoSuchMethodException e) { 210 e.printStackTrace(); 211 } 212 if (complianceSuite == null) 213 return null; 214 215 // add tests 216 for (int i=0, m=testClasses.size(); i<m ; i++) { 217 Class testClass = (Class)testClasses.get(i); 218 TestSuite suite = new TestSuite(testClass.getName()); 219 List tests = buildTestsList(testClass); 220 for (int index=0, size=tests.size(); index<size; index++) { 221 suite.addTest((Test)tests.get(index)); 222 } 223 complianceSuite.addTest(suite); 224 } 225 return complianceSuite; 226 } 227 228 /** 229 * Build a regression test setup suite for a minimal compliance and a test suite to run. 230 * Returned test suite has only one child: {@link RegressionTestSetup} test suite. 231 * Name of returned suite is the name of given test suite class. 232 * The test suite will be run iff the compliance is at least the specified one. 233 * 234 * @param minimalCompliance The unqie compliance level used for this test suite. 235 * @param evaluationTestClass The test suite to run. 236 * @return built test suite (see {@link TestSuite} 237 */ buildMinimalComplianceTestSuite(Class evaluationTestClass, int minimalCompliance)238 public static Test buildMinimalComplianceTestSuite(Class evaluationTestClass, int minimalCompliance) { 239 TestSuite suite = new TestSuite(evaluationTestClass.getName()); 240 int complianceLevels = AbstractCompilerTest.getPossibleComplianceLevels(); 241 int level13 = complianceLevels & AbstractCompilerTest.F_1_3; 242 if (level13 != 0) { 243 if (level13 < minimalCompliance) { 244 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance "+CompilerOptions.versionFromJdkLevel(ClassFileConstants.JDK1_3)+"!"); 245 } else { 246 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_3)); 247 } 248 } 249 int level14 = complianceLevels & AbstractCompilerTest.F_1_4; 250 if (level14 != 0) { 251 if (level14 < minimalCompliance) { 252 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance "+CompilerOptions.versionFromJdkLevel(ClassFileConstants.JDK1_4)+"!"); 253 } else { 254 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_4)); 255 } 256 } 257 int level15 = complianceLevels & AbstractCompilerTest.F_1_5; 258 if (level15 != 0) { 259 if (level15 < minimalCompliance) { 260 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance "+CompilerOptions.versionFromJdkLevel(ClassFileConstants.JDK1_5)+"!"); 261 } else { 262 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_5)); 263 } 264 } 265 int level16 = complianceLevels & AbstractCompilerTest.F_1_6; 266 if (level16 != 0) { 267 if (level16 < minimalCompliance) { 268 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance "+CompilerOptions.versionFromJdkLevel(ClassFileConstants.JDK1_6)+"!"); 269 } else { 270 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_6)); 271 } 272 } 273 int level17 = complianceLevels & AbstractCompilerTest.F_1_7; 274 if (level17 != 0) { 275 if (level17 < minimalCompliance) { 276 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance "+CompilerOptions.versionFromJdkLevel(ClassFileConstants.JDK1_7)+"!"); 277 } else { 278 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_7)); 279 } 280 } 281 int level18 = complianceLevels & AbstractCompilerTest.F_1_8; 282 if (level18 != 0) { 283 if (level18 < minimalCompliance) { 284 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance "+CompilerOptions.versionFromJdkLevel(ClassFileConstants.JDK1_8)+"!"); 285 } else { 286 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK1_8)); 287 } 288 } 289 int level19 = complianceLevels & AbstractCompilerTest.F_9; 290 if (level19 != 0) { 291 if (level19 < minimalCompliance) { 292 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance "+CompilerOptions.versionFromJdkLevel(ClassFileConstants.JDK9)+"!"); 293 } else { 294 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK9)); 295 } 296 } 297 int level10 = complianceLevels & AbstractCompilerTest.F_10; 298 if (level10 != 0) { 299 if (level10 < minimalCompliance) { 300 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance "+CompilerOptions.versionFromJdkLevel(ClassFileConstants.JDK10)+"!"); 301 } else { 302 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.JDK10)); 303 } 304 } 305 int level11 = complianceLevels & AbstractCompilerTest.F_11; 306 if (level11 != 0) { 307 if (level11 < minimalCompliance) { 308 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance 11!"); 309 } else { 310 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11))); 311 } 312 } 313 int level12 = complianceLevels & AbstractCompilerTest.F_12; 314 if (level12 != 0) { 315 if (level12 < minimalCompliance) { 316 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance 12!"); 317 } else { 318 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12))); 319 } 320 } 321 int level_13 = complianceLevels & AbstractCompilerTest.F_13; 322 if (level_13 != 0) { 323 if (level_13 < minimalCompliance) { 324 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance 13!"); 325 } else { 326 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_13))); 327 } 328 } 329 checkCompliance(evaluationTestClass, minimalCompliance, suite, complianceLevels, AbstractCompilerTest.F_14, ClassFileConstants.MAJOR_VERSION_14, 14); 330 return suite; 331 } checkCompliance(Class evaluationTestClass, int minimalCompliance, TestSuite suite, int complianceLevels, int abstractCompilerTestCompliance, int classFileConstantsVersion, int errMessageCompliance)332 private static void checkCompliance(Class evaluationTestClass, int minimalCompliance, TestSuite suite, 333 int complianceLevels, int abstractCompilerTestCompliance, int classFileConstantsVersion, int errMessageCompliance) { 334 int lev = complianceLevels & abstractCompilerTestCompliance; 335 if (lev != 0) { 336 if (lev < minimalCompliance) { 337 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance" + errMessageCompliance + "!"); 338 } else { 339 suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(classFileConstantsVersion))); 340 } 341 } 342 } 343 344 /** 345 * Build a regression test setup suite for a compliance and a test suite to run. 346 * Returned test suite has only one child: {@link RegressionTestSetup} test suite. 347 * Name of returned suite is the name of given test suite class. 348 * 349 * @param uniqueCompliance The unique compliance level used for this test suite. 350 * @param evaluationTestClass The test suite to run. 351 * @return built test suite (see {@link TestSuite} 352 */ buildUniqueComplianceTestSuite(Class evaluationTestClass, long uniqueCompliance)353 public static Test buildUniqueComplianceTestSuite(Class evaluationTestClass, long uniqueCompliance) { 354 long highestLevel = highestComplianceLevels(); 355 if (highestLevel < uniqueCompliance) { 356 String complianceString; 357 if (highestLevel == ClassFileConstants.JDK10) 358 complianceString = "10"; 359 else if (highestLevel == ClassFileConstants.JDK9) 360 complianceString = "9"; 361 else if (highestLevel == ClassFileConstants.JDK1_8) 362 complianceString = "1.8"; 363 else if (highestLevel == ClassFileConstants.JDK1_7) 364 complianceString = "1.7"; 365 else if (highestLevel == ClassFileConstants.JDK1_6) 366 complianceString = "1.6"; 367 else if (highestLevel == ClassFileConstants.JDK1_5) 368 complianceString = "1.5"; 369 else if (highestLevel == ClassFileConstants.JDK1_4) 370 complianceString = "1.4"; 371 else if (highestLevel == ClassFileConstants.JDK1_3) 372 complianceString = "1.3"; 373 else { 374 highestLevel = ClassFileConstants.getLatestJDKLevel(); 375 if (highestLevel > 0) { 376 complianceString = CompilerOptions.versionFromJdkLevel(highestLevel); 377 } else { 378 complianceString = "unknown"; 379 } 380 381 } 382 383 System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance "+complianceString+"!"); 384 return new TestSuite(); 385 } 386 TestSuite complianceSuite = new RegressionTestSetup(uniqueCompliance); 387 List tests = buildTestsList(evaluationTestClass); 388 for (int index=0, size=tests.size(); index<size; index++) { 389 complianceSuite.addTest((Test)tests.get(index)); 390 } 391 return complianceSuite; 392 } 393 394 /* 395 * Returns the highest compliance level this VM instance can run. 396 */ highestComplianceLevels()397 public static long highestComplianceLevels() { 398 int complianceLevels = AbstractCompilerTest.getPossibleComplianceLevels(); 399 if ((complianceLevels & AbstractCompilerTest.F_14) != 0) { 400 return ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_14); 401 } 402 if ((complianceLevels & AbstractCompilerTest.F_13) != 0) { 403 return ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_13); 404 } 405 if ((complianceLevels & AbstractCompilerTest.F_12) != 0) { 406 return ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12); 407 } 408 if ((complianceLevels & AbstractCompilerTest.F_11) != 0) { 409 return ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11); 410 } 411 if ((complianceLevels & AbstractCompilerTest.F_10) != 0) { 412 return ClassFileConstants.JDK10; 413 } 414 if ((complianceLevels & AbstractCompilerTest.F_9) != 0) { 415 return ClassFileConstants.JDK9; 416 } 417 if ((complianceLevels & AbstractCompilerTest.F_1_8) != 0) { 418 return ClassFileConstants.JDK1_8; 419 } 420 if ((complianceLevels & AbstractCompilerTest.F_1_7) != 0) { 421 return ClassFileConstants.JDK1_7; 422 } 423 if ((complianceLevels & AbstractCompilerTest.F_1_6) != 0) { 424 return ClassFileConstants.JDK1_6; 425 } 426 if ((complianceLevels & AbstractCompilerTest.F_1_5) != 0) { 427 return ClassFileConstants.JDK1_5; 428 } 429 if ((complianceLevels & AbstractCompilerTest.F_1_4) != 0) { 430 return ClassFileConstants.JDK1_4; 431 } 432 return ClassFileConstants.JDK1_3; 433 } 434 initReflectionVersion()435 static void initReflectionVersion() { 436 if (isJRE9Plus) { 437 reflectNestedClassUseDollar = true; 438 System.out.println("reflectNestedClassUseDollar="+reflectNestedClassUseDollar+" due to isJRE9Plus"); 439 } else { 440 String version = System.getProperty("java.version"); 441 if (version.startsWith("1.8.0_")) { 442 int build = Integer.parseInt(version.substring("1.8.0_".length())); 443 reflectNestedClassUseDollar = build >= 171; 444 } else if (version.startsWith("1.8.0-")) { 445 // Some versions start with 1.8.0- but don't have build qualifier. 446 // Just assume they are > 171 build. Nothing much can be done. 447 reflectNestedClassUseDollar = true; 448 } else { 449 throw new IllegalStateException("Unrecognized Java version: "+version); 450 } 451 System.out.println("reflectNestedClassUseDollar="+reflectNestedClassUseDollar+" based on version="+version); 452 } 453 } 454 455 /* 456 * Returns the possible compliance levels this VM instance can run. 457 */ getPossibleComplianceLevels()458 public static int getPossibleComplianceLevels() { 459 if (possibleComplianceLevels == UNINITIALIZED) { 460 String specVersion = System.getProperty("java.specification.version"); 461 isJRE14Plus = CompilerOptions.VERSION_14.equals(specVersion); 462 isJRE13Plus = isJRE14Plus || CompilerOptions.VERSION_13.equals(specVersion); 463 isJRE12Plus = isJRE13Plus || CompilerOptions.VERSION_12.equals(specVersion); 464 isJRE11Plus = isJRE12Plus || CompilerOptions.VERSION_11.equals(specVersion); 465 isJRE9Plus = isJRE11Plus || CompilerOptions.VERSION_9.equals(specVersion) 466 || CompilerOptions.VERSION_10.equals(specVersion); 467 initReflectionVersion(); 468 String compliances = System.getProperty("compliance"); 469 if (compliances != null) { 470 possibleComplianceLevels = 0; 471 for (String compliance : compliances.split(",")) { 472 if (CompilerOptions.VERSION_1_3.equals(compliance)) { 473 possibleComplianceLevels |= RUN_JAVAC ? NONE : F_1_3; 474 } else if (CompilerOptions.VERSION_1_4.equals(compliance)) { 475 possibleComplianceLevels |= RUN_JAVAC ? NONE : F_1_4; 476 } else if (CompilerOptions.VERSION_1_5.equals(compliance)) { 477 possibleComplianceLevels |= F_1_5; 478 } else if (CompilerOptions.VERSION_1_6.equals(compliance)) { 479 possibleComplianceLevels |= F_1_6; 480 } else if (CompilerOptions.VERSION_1_7.equals(compliance)) { 481 possibleComplianceLevels |= F_1_7; 482 } else if (CompilerOptions.VERSION_1_8.equals(compliance)) { 483 possibleComplianceLevels |= F_1_8; 484 } else if (CompilerOptions.VERSION_9.equals(compliance)) { 485 possibleComplianceLevels |= F_9; 486 } else if (CompilerOptions.VERSION_10.equals(compliance)) { 487 possibleComplianceLevels |= F_10; 488 } else if (CompilerOptions.VERSION_11.equals(compliance)) { 489 possibleComplianceLevels |= F_11; 490 } else if (CompilerOptions.VERSION_12.equals(compliance)) { 491 possibleComplianceLevels |= F_12; 492 } else if (CompilerOptions.VERSION_13.equals(compliance)) { 493 possibleComplianceLevels |= F_13; 494 } else if (CompilerOptions.VERSION_14.equals(compliance)) { 495 possibleComplianceLevels |= F_14; 496 } else { 497 System.out.println("Ignoring invalid compliance (" + compliance + ")"); 498 System.out.print("Use one of "); 499 System.out.print(CompilerOptions.VERSION_1_3 + ", "); 500 System.out.print(CompilerOptions.VERSION_1_4 + ", "); 501 System.out.print(CompilerOptions.VERSION_1_5 + ", "); 502 System.out.print(CompilerOptions.VERSION_1_6 + ", "); 503 System.out.print(CompilerOptions.VERSION_1_7 + ", "); 504 System.out.print(CompilerOptions.VERSION_1_8 + ", "); 505 System.out.print(CompilerOptions.VERSION_1_8 + ", "); 506 System.out.print(CompilerOptions.VERSION_9 + ", "); 507 System.out.print(CompilerOptions.VERSION_10 + ", "); 508 System.out.print(CompilerOptions.VERSION_11 + ", "); 509 System.out.print(CompilerOptions.VERSION_12 + ", "); 510 System.out.print(CompilerOptions.VERSION_13 + ", "); 511 System.out.println(CompilerOptions.VERSION_14); 512 } 513 } 514 if (possibleComplianceLevels == 0) { 515 System.out.println("Defaulting to all possible compliances"); 516 possibleComplianceLevels = UNINITIALIZED; 517 } 518 } 519 if (possibleComplianceLevels == UNINITIALIZED) { 520 if (!RUN_JAVAC) { 521 possibleComplianceLevels = F_1_3; 522 boolean canRun1_4 = !"1.0".equals(specVersion) 523 && !CompilerOptions.VERSION_1_1.equals(specVersion) 524 && !CompilerOptions.VERSION_1_2.equals(specVersion) 525 && !CompilerOptions.VERSION_1_3.equals(specVersion); 526 if (canRun1_4) { 527 possibleComplianceLevels |= F_1_4; 528 } 529 boolean canRun1_5 = canRun1_4 && !CompilerOptions.VERSION_1_4.equals(specVersion); 530 if (canRun1_5) { 531 possibleComplianceLevels |= F_1_5; 532 } 533 boolean canRun1_6 = canRun1_5 && !CompilerOptions.VERSION_1_5.equals(specVersion); 534 if (canRun1_6) { 535 possibleComplianceLevels |= F_1_6; 536 } 537 boolean canRun1_7 = canRun1_6 && !CompilerOptions.VERSION_1_6.equals(specVersion); 538 if (canRun1_7) { 539 possibleComplianceLevels |= F_1_7; 540 } 541 boolean canRun1_8 = canRun1_7 && !CompilerOptions.VERSION_1_7.equals(specVersion); 542 if (canRun1_8) { 543 possibleComplianceLevels |= F_1_8; 544 } 545 boolean canRun9 = canRun1_8 && !CompilerOptions.VERSION_1_8.equals(specVersion); 546 if (canRun9) { 547 possibleComplianceLevels |= F_9; 548 } 549 boolean canRun10 = canRun9 && !CompilerOptions.VERSION_9.equals(specVersion); 550 if (canRun10) { 551 possibleComplianceLevels |= F_10; 552 } 553 boolean canRun11 = canRun10 && !CompilerOptions.VERSION_10.equals(specVersion); 554 if (canRun11) { 555 possibleComplianceLevels |= F_11; 556 } 557 boolean canRun12 = canRun11 && !CompilerOptions.VERSION_11.equals(specVersion); 558 if (canRun12) { 559 possibleComplianceLevels |= F_12; 560 } 561 boolean canRun13 = canRun12 && !CompilerOptions.VERSION_12.equals(specVersion); 562 if (canRun13) { 563 possibleComplianceLevels |= F_13; 564 } 565 boolean canRun14 = canRun13 && !CompilerOptions.VERSION_13.equals(specVersion); 566 if (canRun14) { 567 possibleComplianceLevels |= F_14; 568 } 569 } else if ("1.0".equals(specVersion) 570 || CompilerOptions.VERSION_1_1.equals(specVersion) 571 || CompilerOptions.VERSION_1_2.equals(specVersion) 572 || CompilerOptions.VERSION_1_3.equals(specVersion) 573 || CompilerOptions.VERSION_1_4.equals(specVersion)) { 574 possibleComplianceLevels = NONE; 575 } else { 576 possibleComplianceLevels = F_1_5; 577 if (!CompilerOptions.VERSION_1_5.equals(specVersion)) { 578 possibleComplianceLevels |= F_1_6; 579 if (!CompilerOptions.VERSION_1_6.equals(specVersion)) { 580 possibleComplianceLevels |= F_1_7; 581 if (!CompilerOptions.VERSION_1_7.equals(specVersion)) { 582 possibleComplianceLevels |= F_1_8; 583 if (!CompilerOptions.VERSION_1_8.equals(specVersion)) { 584 possibleComplianceLevels |= F_9; 585 if (!CompilerOptions.VERSION_9.equals(specVersion)) { 586 possibleComplianceLevels |= F_10; 587 if (!CompilerOptions.VERSION_10.equals(specVersion)) { 588 possibleComplianceLevels |= F_11; 589 if (!CompilerOptions.VERSION_11.equals(specVersion)) { 590 possibleComplianceLevels |= F_12; 591 if (!CompilerOptions.VERSION_12.equals(specVersion)) { 592 possibleComplianceLevels |= F_13; 593 if (!CompilerOptions.VERSION_13.equals(specVersion)) { 594 possibleComplianceLevels |= F_14; 595 } 596 } 597 } 598 } 599 } 600 } 601 } 602 } 603 } 604 } 605 } 606 } 607 if (possibleComplianceLevels == NONE) { 608 System.out.println("Skipping all compliances (found none compatible with run.javac=enabled)."); 609 } 610 return possibleComplianceLevels; 611 } 612 613 /* 614 * Returns a test suite including the tests defined by the given classes for all possible complianceLevels 615 * and using the given setup class (CompilerTestSetup or a subclass) 616 */ suite(String suiteName, Class setupClass, ArrayList testClasses)617 public static Test suite(String suiteName, Class setupClass, ArrayList testClasses) { 618 TestSuite all = new TestSuite(suiteName); 619 int complianceLevels = AbstractCompilerTest.getPossibleComplianceLevels(); 620 if ((complianceLevels & AbstractCompilerTest.F_1_3) != 0) { 621 all.addTest(suiteForComplianceLevel(ClassFileConstants.JDK1_3, setupClass, testClasses)); 622 } 623 if ((complianceLevels & AbstractCompilerTest.F_1_4) != 0) { 624 all.addTest(suiteForComplianceLevel(ClassFileConstants.JDK1_4, setupClass, testClasses)); 625 } 626 if ((complianceLevels & AbstractCompilerTest.F_1_5) != 0) { 627 all.addTest(suiteForComplianceLevel(ClassFileConstants.JDK1_5, setupClass, testClasses)); 628 } 629 return all; 630 } 631 632 /* 633 * Returns a test suite including the tests defined by the given classes for the given complianceLevel 634 * (see AbstractCompilerTest for valid values) and using the given setup class (CompilerTestSetup or a subclass) 635 */ suiteForComplianceLevel(long complianceLevel, Class setupClass, ArrayList testClasses)636 public static Test suiteForComplianceLevel(long complianceLevel, Class setupClass, ArrayList testClasses) { 637 // call the setup constructor with the compliance level 638 TestSuite suite = null; 639 try { 640 Constructor constructor = setupClass.getConstructor(new Class[]{String.class}); 641 suite = (TestSuite)constructor.newInstance(new Object[]{CompilerOptions.versionFromJdkLevel(complianceLevel)}); 642 } catch (IllegalAccessException e) { 643 e.printStackTrace(); 644 } catch (InstantiationException e) { 645 e.printStackTrace(); 646 } catch (InvocationTargetException e) { 647 e.getTargetException().printStackTrace(); 648 } catch (NoSuchMethodException e) { 649 e.printStackTrace(); 650 } 651 if (suite == null) 652 return null; 653 654 // add tests 655 Class testClass; 656 if (testClasses.size() == 1) { 657 suite = new TestSuite(testClass = (Class)testClasses.get(0), CompilerOptions.versionFromJdkLevel(complianceLevel)); 658 TESTS_COUNTERS.put(testClass.getName(), Integer.valueOf(suite.countTestCases())); 659 } else { 660 suite = new TestSuite(CompilerOptions.versionFromJdkLevel(complianceLevel)); 661 for (int i = 0, length = testClasses.size(); i < length; i++) { 662 TestSuite innerSuite = new TestSuite(testClass = (Class)testClasses.get(i)); 663 TESTS_COUNTERS.put(testClass.getName(), Integer.valueOf(innerSuite.countTestCases())); 664 suite.addTest(innerSuite); 665 } 666 } 667 return suite; 668 } 669 setupSuite(Class clazz)670 public static Test setupSuite(Class clazz) { 671 ArrayList testClasses = new ArrayList(); 672 testClasses.add(clazz); 673 return suite(clazz.getName(), RegressionTestSetup.class, testClasses); 674 } 675 buildTestSuite(Class evaluationTestClass)676 public static Test buildTestSuite(Class evaluationTestClass) { 677 if (TESTS_PREFIX != null || TESTS_NAMES != null || TESTS_NUMBERS!=null || TESTS_RANGE !=null) { 678 return buildTestSuite(evaluationTestClass, highestComplianceLevels()); 679 } 680 return setupSuite(evaluationTestClass); 681 } 682 buildTestSuite(Class evaluationTestClass, long complianceLevel)683 public static Test buildTestSuite(Class evaluationTestClass, long complianceLevel) { 684 TestSuite suite = new RegressionTestSetup(complianceLevel); 685 List tests = buildTestsList(evaluationTestClass); 686 for (int index=0, size=tests.size(); index<size; index++) { 687 suite.addTest((Test)tests.get(index)); 688 } 689 String className = evaluationTestClass.getName(); 690 Integer testsNb; 691 int newTestsNb = suite.countTestCases(); 692 if ((testsNb = (Integer) TESTS_COUNTERS.get(className)) != null) 693 newTestsNb += testsNb.intValue(); 694 TESTS_COUNTERS.put(className, Integer.valueOf(newTestsNb)); 695 return suite; 696 } 697 698 isJRELevel(int compliance)699 public static boolean isJRELevel(int compliance) { 700 return (AbstractCompilerTest.getPossibleComplianceLevels() & compliance) != 0; 701 } 702 decorateAnnotationValueLiteral(String val)703 public String decorateAnnotationValueLiteral(String val) { 704 if (!isJRE9Plus) { 705 return val; 706 } 707 StringBuilder builder = new StringBuilder(val); 708 builder.insert(0, "\""); 709 builder.append("\""); 710 return builder.toString(); 711 } 712 AbstractCompilerTest(String name)713 public AbstractCompilerTest(String name) { 714 super(name); 715 } 716 getCompilerOptions()717 protected Map getCompilerOptions() { 718 Map options = new CompilerOptions().getMap(); 719 options.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.IGNORE); 720 if (this.complianceLevel == ClassFileConstants.JDK1_3) { 721 options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_3); 722 options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3); 723 options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1); 724 } else if (this.complianceLevel == ClassFileConstants.JDK1_4) { 725 options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4); 726 options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4); 727 options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); 728 } else if (this.complianceLevel == ClassFileConstants.JDK1_5) { 729 options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5); 730 options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); 731 options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); 732 } else if (this.complianceLevel == ClassFileConstants.JDK1_6) { 733 options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6); 734 options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6); 735 options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); 736 } else if (this.complianceLevel == ClassFileConstants.JDK1_7) { 737 options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7); 738 options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7); 739 options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7); 740 } else if (this.complianceLevel == ClassFileConstants.JDK1_8) { 741 options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8); 742 options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8); 743 options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8); 744 } else if (this.complianceLevel == ClassFileConstants.JDK9) { 745 options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_9); 746 options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_9); 747 options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9); 748 } else if (this.complianceLevel == ClassFileConstants.JDK10) { 749 options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_10); 750 options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10); 751 options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10); 752 } else { 753 // This is already good enough to cover versions from future 754 // (as long as versionFromJdkLevel does its job) 755 String ver = CompilerOptions.versionFromJdkLevel(this.complianceLevel); 756 options.put(CompilerOptions.OPTION_Compliance, ver); 757 options.put(CompilerOptions.OPTION_Source, ver); 758 options.put(CompilerOptions.OPTION_TargetPlatform, ver); 759 } 760 return options; 761 } 762 getName()763 public String getName() { 764 String name = super.getName(); 765 if (this.complianceLevel != 0) { 766 name = name + " - " + CompilerOptions.versionFromJdkLevel(this.complianceLevel); 767 } 768 return name; 769 } 770 getVersionString(long compliance)771 protected static String getVersionString(long compliance) { 772 String version = "version 14 : 58.0"; 773 if (compliance < ClassFileConstants.JDK9) return "version 1.8 : 52.0"; 774 if (compliance == ClassFileConstants.JDK9) return "version 9 : 53.0"; 775 if (compliance == ClassFileConstants.JDK10) return "version 10 : 54.0"; 776 if (compliance > ClassFileConstants.JDK10) { 777 String ver = CompilerOptions.versionFromJdkLevel(compliance); 778 int major = Integer.parseInt(ver) + ClassFileConstants.MAJOR_VERSION_0; 779 return "version " + ver + " : " + major + ".0"; 780 } 781 if (compliance >= ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_14)) return version; // keep this stmt for search for next bump up 782 return version; 783 } 784 initialize(CompilerTestSetup setUp)785 public void initialize(CompilerTestSetup setUp) { 786 this.complianceLevel = setUp.complianceLevel; 787 this.enableAPT = System.getProperty("enableAPT") != null; 788 } 789 testName()790 protected String testName() { 791 return super.getName(); 792 } 793 794 // Output files management 795 protected IPath outputRootDirectoryPath = new Path(Util.getOutputDirectory()); 796 protected File outputTestDirectory; 797 798 /** 799 * Create a test specific output directory as a subdirectory of 800 * outputRootDirectory, given a subdirectory path. The whole 801 * subtree is created as needed. outputTestDirectoryPath is 802 * modified according to the latest call to this method. 803 * @param suffixPath a valid relative path for the subdirectory 804 */ createOutputTestDirectory(String suffixPath)805 protected void createOutputTestDirectory(String suffixPath) { 806 this.outputTestDirectory = new File(this.outputRootDirectoryPath.toFile(), suffixPath); 807 if (!this.outputTestDirectory.exists()) { 808 this.outputTestDirectory.mkdirs(); 809 } 810 } 811 /* 812 * Write given source test files in current output sub-directory. 813 * Use test name for this sub-directory name (ie. test001, test002, etc...) 814 */ writeFiles(String[] testFiles)815 protected void writeFiles(String[] testFiles) { 816 createOutputTestDirectory(testName()); 817 818 // Write each given test file 819 for (int i = 0, length = testFiles.length; i < length; ) { 820 String fileName = testFiles[i++]; 821 String contents = testFiles[i++]; 822 File file = new File(this.outputTestDirectory, fileName); 823 if (fileName.lastIndexOf('/') >= 0) { 824 File dir = file.getParentFile(); 825 if (!dir.exists()) { 826 dir.mkdirs(); 827 } 828 } 829 Util.writeToFile(contents, file.getPath()); 830 } 831 } 832 833 // Summary display 834 // Used by AbstractRegressionTest for javac comparison tests 835 protected static Map TESTS_COUNTERS = new HashMap(); 836 } 837