1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package libcore.java.lang.reflect; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertNotSame; 23 import static org.junit.Assert.assertSame; 24 import static org.junit.Assert.assertTrue; 25 import static org.junit.Assert.fail; 26 27 import dalvik.system.PathClassLoader; 28 29 import libcore.io.Streams; 30 31 import java.io.File; 32 import java.io.FileOutputStream; 33 import java.io.InputStream; 34 import java.lang.annotation.ElementType; 35 import java.lang.annotation.Retention; 36 import java.lang.annotation.RetentionPolicy; 37 import java.lang.annotation.Target; 38 import java.lang.reflect.Constructor; 39 import java.lang.reflect.Executable; 40 import java.lang.reflect.MalformedParametersException; 41 import java.lang.reflect.Method; 42 import java.lang.reflect.Modifier; 43 import java.lang.reflect.Parameter; 44 import java.text.NumberFormat; 45 import java.util.Arrays; 46 import java.util.concurrent.Callable; 47 import java.util.function.Function; 48 49 import org.junit.Before; 50 import org.junit.Ignore; 51 import org.junit.Test; 52 import org.junit.runner.RunWith; 53 import org.junit.runners.JUnit4; 54 55 56 /** 57 * Tests for {@link Parameter}. For annotation-related tests see 58 * {@link libcore.java.lang.reflect.annotations.AnnotatedElementParameterTest} and 59 * {@link libcore.java.lang.reflect.annotations.ExecutableParameterTest}. 60 * 61 * <p>Tests suffixed with _withMetadata() require parameter metadata compiled in to work properly. 62 * These are handled by loading pre-compiled .dex files. 63 * See also {@link DependsOnParameterMetadata}. 64 */ 65 @RunWith(JUnit4.class) 66 public class ParameterTest { 67 68 /** 69 * A ClassLoader that can be used to load the 70 * libcore.java.lang.reflect.parameter.ParameterMetadataTestClasses class and its nested 71 * classes. The loaded classes have valid metadata that can be created by a valid Java compiler 72 * / Android dexer. 73 */ 74 private ClassLoader classesWithMetadataClassLoader; 75 76 /** 77 * A ClassLoader that can be used to load the 78 * libcore.java.lang.reflect.parameter.MetadataVariations class. 79 * The loaded class has invalid metadata that could not be created by a valid Java compiler / 80 * Android dexer. 81 */ 82 private ClassLoader metadataVariationsClassLoader; 83 84 @Before setUp()85 public void setUp() throws Exception { 86 File tempDir = File.createTempFile("tempDir", ""); 87 assertTrue(tempDir.delete()); 88 assertTrue(tempDir.mkdirs()); 89 90 classesWithMetadataClassLoader = 91 createClassLoaderForResource(tempDir, "parameter-metadata-test.jar"); 92 String metadataVariationsResourcePath = 93 "libcore/java/lang/reflect/parameter/metadata_variations.dex"; 94 metadataVariationsClassLoader = 95 createClassLoaderForResource(tempDir, metadataVariationsResourcePath); 96 } 97 98 /** 99 * A source annotation used to mark code below with behavior that is highly dependent on 100 * parameter metadata. It is intended to bring readers here for the following: 101 * 102 * <p>Unless the compiler supports (and is configured to enable) storage of metadata 103 * for parameters, the runtime does not have access to the parameter name from the source and 104 * some modifier information like "implicit" (AKA "mandated"), "synthetic" and "final". 105 * 106 * <p>This test class is expected to be compiled <em>without</em> requesting that the metadata 107 * be compiled in. dex files that contains classes with metadata are loaded in setUp() and 108 * used from the tests suffixed with "_withMetadata". 109 */ 110 @Retention(RetentionPolicy.SOURCE) 111 @Target(ElementType.METHOD) 112 private @interface DependsOnParameterMetadata {} 113 114 private static class SingleParameter { 115 @SuppressWarnings("unused") SingleParameter(String p0)116 SingleParameter(String p0) {} 117 118 @SuppressWarnings("unused") oneParameter(String p0)119 void oneParameter(String p0) {} 120 } 121 122 @Test testSingleParameterConstructor()123 public void testSingleParameterConstructor() throws Exception { 124 Constructor<?> constructor = SingleParameter.class.getDeclaredConstructor(String.class); 125 checkSingleStringParameter(constructor); 126 } 127 128 @Test testSingleParameterMethod()129 public void testSingleParameterMethod() throws Exception { 130 Method method = SingleParameter.class.getDeclaredMethod("oneParameter", String.class); 131 checkSingleStringParameter(method); 132 } 133 checkSingleStringParameter(Executable executable)134 private static void checkSingleStringParameter(Executable executable) { 135 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 136 helper.checkStandardParametersBehavior() 137 .checkParametersToString("[java.lang.String arg0]") 138 .checkParametersMetadataNotAvailable() 139 .checkParametersNoVarArgs(); 140 141 helper.getParameterTestHelper(0) 142 .checkGetType(String.class) 143 .checkGetParameterizedType("class java.lang.String"); 144 } 145 146 @Test testSingleParameterConstructor_withMetadata()147 public void testSingleParameterConstructor_withMetadata() throws Exception { 148 Class<?> clazz = loadTestInnerClassWithMetadata("SingleParameter"); 149 Constructor<?> constructor = clazz.getDeclaredConstructor(String.class); 150 checkSingleStringParameter_withMetadata(constructor); 151 } 152 153 @Test testSingleParameterMethod_withMetadata()154 public void testSingleParameterMethod_withMetadata() throws Exception { 155 Class<?> clazz = loadTestInnerClassWithMetadata("SingleParameter"); 156 Method method = clazz.getDeclaredMethod("oneParameter", String.class); 157 checkSingleStringParameter_withMetadata(method); 158 } 159 checkSingleStringParameter_withMetadata(Executable executable)160 private static void checkSingleStringParameter_withMetadata(Executable executable) { 161 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 162 helper.checkStandardParametersBehavior() 163 .checkParametersToString("[java.lang.String p0]") 164 .checkParametersNoVarArgs(); 165 166 helper.getParameterTestHelper(0) 167 .checkGetType(String.class) 168 .checkName(true /* expectedNameIsPresent */, "p0") 169 .checkModifiers(0) 170 .checkImplicitAndSynthetic(false, false) 171 .checkGetParameterizedType("class java.lang.String"); 172 } 173 174 private static class GenericParameter { 175 @SuppressWarnings("unused") GenericParameter(Function<String, Integer> p0)176 GenericParameter(Function<String, Integer> p0) {} 177 178 @SuppressWarnings("unused") genericParameter(Function<String, Integer> p0)179 void genericParameter(Function<String, Integer> p0) {} 180 } 181 182 @Test testGenericParameterConstructor()183 public void testGenericParameterConstructor() throws Exception { 184 Constructor<?> constructor = GenericParameter.class.getDeclaredConstructor(Function.class); 185 checkGenericParameter(constructor); 186 } 187 188 @Test testGenericParameterMethod()189 public void testGenericParameterMethod() throws Exception { 190 Method method = GenericParameter.class.getDeclaredMethod( 191 "genericParameter", Function.class); 192 checkGenericParameter(method); 193 } 194 checkGenericParameter(Executable executable)195 private static void checkGenericParameter(Executable executable) { 196 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 197 helper.checkStandardParametersBehavior() 198 .checkParametersToString( 199 "[java.util.function.Function<java.lang.String, java.lang.Integer> arg0]") 200 .checkParametersMetadataNotAvailable() 201 .checkParametersNoVarArgs(); 202 203 helper.getParameterTestHelper(0) 204 .checkGetType(Function.class) 205 .checkGetParameterizedType( 206 "java.util.function.Function<java.lang.String, java.lang.Integer>"); 207 } 208 209 @Test testGenericParameterConstructor_withMetadata()210 public void testGenericParameterConstructor_withMetadata() throws Exception { 211 Class<?> clazz = loadTestInnerClassWithMetadata("GenericParameter"); 212 Constructor<?> constructor = clazz.getDeclaredConstructor(Function.class); 213 checkGenericParameter_withMetadata(constructor); 214 } 215 216 @Test testGenericParameterMethod_withMetadata()217 public void testGenericParameterMethod_withMetadata() throws Exception { 218 Class<?> clazz = loadTestInnerClassWithMetadata("GenericParameter"); 219 Method method = clazz.getDeclaredMethod("genericParameter", Function.class); 220 checkGenericParameter_withMetadata(method); 221 } 222 checkGenericParameter_withMetadata(Executable executable)223 private static void checkGenericParameter_withMetadata(Executable executable) { 224 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 225 helper.checkStandardParametersBehavior() 226 .checkParametersToString( 227 "[java.util.function.Function<java.lang.String, java.lang.Integer> p0]") 228 .checkParametersNoVarArgs(); 229 230 helper.getParameterTestHelper(0) 231 .checkGetType(Function.class) 232 .checkName(true /* expectedNameIsPresent */, "p0") 233 .checkModifiers(0) 234 .checkImplicitAndSynthetic(false, false) 235 .checkGetParameterizedType( 236 "java.util.function.Function<java.lang.String, java.lang.Integer>"); 237 } 238 239 private static class TwoParameters { 240 @SuppressWarnings("unused") TwoParameters(String p0, Integer p1)241 TwoParameters(String p0, Integer p1) {} 242 @SuppressWarnings("unused") twoParameters(String p0, Integer p1)243 void twoParameters(String p0, Integer p1) {} 244 } 245 246 @Test testTwoParameterConstructor()247 public void testTwoParameterConstructor() throws Exception { 248 Constructor<?> constructor = 249 TwoParameters.class.getDeclaredConstructor(String.class, Integer.class); 250 checkTwoParameters(constructor); 251 } 252 253 @Test testTwoParameterMethod()254 public void testTwoParameterMethod() throws Exception { 255 Method method = TwoParameters.class.getDeclaredMethod( 256 "twoParameters", String.class, Integer.class); 257 checkTwoParameters(method); 258 } 259 checkTwoParameters(Executable executable)260 private static void checkTwoParameters(Executable executable) { 261 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 262 helper.checkStandardParametersBehavior() 263 .checkParametersToString("[java.lang.String arg0, java.lang.Integer arg1]") 264 .checkParametersMetadataNotAvailable() 265 .checkParametersNoVarArgs(); 266 267 helper.getParameterTestHelper(0) 268 .checkGetType(String.class) 269 .checkGetParameterizedType("class java.lang.String"); 270 271 helper.getParameterTestHelper(1) 272 .checkGetType(Integer.class) 273 .checkGetParameterizedType("class java.lang.Integer"); 274 } 275 276 @Test testTwoParameterConstructor_withMetadata()277 public void testTwoParameterConstructor_withMetadata() throws Exception { 278 Class<?> clazz = loadTestInnerClassWithMetadata("TwoParameters"); 279 Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, Integer.class); 280 checkTwoParameters_withMetadata(constructor); 281 } 282 283 @Test testTwoParameterMethod_withMetadata()284 public void testTwoParameterMethod_withMetadata() throws Exception { 285 Class<?> clazz = loadTestInnerClassWithMetadata("TwoParameters"); 286 Method method = clazz.getDeclaredMethod("twoParameters", String.class, Integer.class); 287 checkTwoParameters_withMetadata(method); 288 } 289 checkTwoParameters_withMetadata(Executable executable)290 private static void checkTwoParameters_withMetadata(Executable executable) { 291 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 292 helper.checkStandardParametersBehavior() 293 .checkParametersToString("[java.lang.String p0, java.lang.Integer p1]") 294 .checkParametersNoVarArgs(); 295 296 helper.getParameterTestHelper(0) 297 .checkGetType(String.class) 298 .checkName(true /* expectedNameIsPresent */, "p0") 299 .checkModifiers(0) 300 .checkImplicitAndSynthetic(false, false) 301 .checkGetParameterizedType("class java.lang.String"); 302 303 helper.getParameterTestHelper(1) 304 .checkGetType(Integer.class) 305 .checkName(true /* expectedNameIsPresent */, "p1") 306 .checkModifiers(0) 307 .checkImplicitAndSynthetic(false, false) 308 .checkGetParameterizedType("class java.lang.Integer"); 309 } 310 311 private static class FinalParameter { 312 @SuppressWarnings("unused") FinalParameter(final String p0)313 FinalParameter(final String p0) {} 314 @SuppressWarnings("unused") finalParameter(final String p0)315 void finalParameter(final String p0) {} 316 } 317 318 @Test testFinalParameterConstructor()319 public void testFinalParameterConstructor() throws Exception { 320 Constructor<?> constructor = FinalParameter.class.getDeclaredConstructor(String.class); 321 checkFinalParameter(constructor); 322 } 323 324 @Test testFinalParameterMethod()325 public void testFinalParameterMethod() throws Exception { 326 Method method = FinalParameter.class.getDeclaredMethod("finalParameter", String.class); 327 checkFinalParameter(method); 328 } 329 checkFinalParameter(Executable executable)330 private static void checkFinalParameter(Executable executable) { 331 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 332 helper.checkStandardParametersBehavior() 333 .checkParametersToString("[java.lang.String arg0]") 334 .checkParametersMetadataNotAvailable() 335 .checkParametersNoVarArgs(); 336 337 helper.getParameterTestHelper(0) 338 .checkGetType(String.class) 339 .checkGetParameterizedType("class java.lang.String"); 340 } 341 342 @Test testFinalParameterConstructor_withMetdata()343 public void testFinalParameterConstructor_withMetdata() throws Exception { 344 Class<?> clazz = loadTestInnerClassWithMetadata("FinalParameter"); 345 Constructor<?> constructor = clazz.getDeclaredConstructor(String.class); 346 checkFinalParameter_withMetadata(constructor); 347 } 348 349 @Test testFinalParameterMethod_withMetdata()350 public void testFinalParameterMethod_withMetdata() throws Exception { 351 Class<?> clazz = loadTestInnerClassWithMetadata("FinalParameter"); 352 Method method = clazz.getDeclaredMethod("finalParameter", String.class); 353 checkFinalParameter_withMetadata(method); 354 } 355 checkFinalParameter_withMetadata(Executable executable)356 private static void checkFinalParameter_withMetadata(Executable executable) { 357 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 358 helper.checkStandardParametersBehavior() 359 .checkParametersToString("[final java.lang.String p0]") 360 .checkParametersNoVarArgs(); 361 362 helper.getParameterTestHelper(0) 363 .checkGetType(String.class) 364 .checkName(true /* expectedNameIsPresent */, "p0") 365 .checkModifiers(Modifier.FINAL) 366 .checkImplicitAndSynthetic(false, false) 367 .checkGetParameterizedType("class java.lang.String"); 368 } 369 370 /** 371 * An inner class, used for checking compiler-inserted parameters: The first parameter is an 372 * instance of the surrounding class. 373 */ 374 private class InnerClass { 375 @SuppressWarnings("unused") InnerClass()376 public InnerClass() {} 377 @SuppressWarnings("unused") InnerClass(String p1)378 public InnerClass(String p1) {} 379 @SuppressWarnings("unused") InnerClass(Function<String, Integer> p1)380 public InnerClass(Function<String, Integer> p1) {} 381 } 382 383 @Test testInnerClassSingleParameter()384 public void testInnerClassSingleParameter() throws Exception { 385 Class<?> outerClass = ParameterTest.class; 386 Class<?> innerClass = InnerClass.class; 387 Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass); 388 389 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 390 helper.checkStandardParametersBehavior() 391 .checkParametersToString("[final " + outerClass.getName() + " arg0]") 392 .checkParametersNoVarArgs(); 393 394 helper.getParameterTestHelper(0) 395 .checkGetType(outerClass) 396 .checkName(false, "arg0") 397 .checkModifiers(4112) // 4112 == Modifier.SYNTHETIC & Modifier.FINAL 398 .checkImplicitAndSynthetic(false, true) 399 .checkGetParameterizedType("class " + outerClass.getName() + ""); 400 } 401 402 @Test testInnerClassSingleParameter_withMetadata()403 public void testInnerClassSingleParameter_withMetadata() throws Exception { 404 Class<?> outerClass = loadTestOuterClassWithMetadata(); 405 Class<?> innerClass = loadTestInnerClassWithMetadata("InnerClass"); 406 Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass); 407 408 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 409 helper.checkStandardParametersBehavior() 410 .checkParametersToString("[final " + outerClass.getName() + " this$0]") 411 .checkParametersNoVarArgs(); 412 413 helper.getParameterTestHelper(0) 414 .checkGetType(outerClass) 415 .checkName(true /* expectedNameIsPresent */, "this$0") 416 .checkModifiers(32784) // 32784 == Modifier.MANDATED & Modifier.FINAL 417 .checkImplicitAndSynthetic(true, false) 418 .checkGetParameterizedType("class " + outerClass.getName()); 419 } 420 421 @Test testInnerClassTwoParameters()422 public void testInnerClassTwoParameters() throws Exception { 423 Class<?> outerClass = ParameterTest.class; 424 Class<?> innerClass = InnerClass.class; 425 Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass, String.class); 426 427 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 428 helper.checkStandardParametersBehavior() 429 .checkParametersToString( 430 "[final " + outerClass.getName() + " arg0, java.lang.String arg1]") 431 .checkParametersNoVarArgs(); 432 433 helper.getParameterTestHelper(0) 434 .checkName(false, "arg0") 435 .checkModifiers(4112) // 4112 == Modifier.SYNTHETIC & Modifier.FINAL 436 .checkImplicitAndSynthetic(false, true) 437 .checkGetType(outerClass) 438 .checkGetParameterizedType("class " + outerClass.getName()); 439 440 helper.getParameterTestHelper(1) 441 .checkName(false, "arg1") 442 .checkModifiers(0) 443 .checkImplicitAndSynthetic(false, false) 444 .checkGetType(String.class) 445 .checkGetParameterizedType("class java.lang.String"); 446 } 447 448 @Test testInnerClassTwoParameters_withMetadata()449 public void testInnerClassTwoParameters_withMetadata() throws Exception { 450 Class<?> outerClass = loadTestOuterClassWithMetadata(); 451 Class<?> innerClass = loadTestInnerClassWithMetadata("InnerClass"); 452 Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass, String.class); 453 454 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 455 helper.checkStandardParametersBehavior() 456 .checkParametersToString( 457 "[final " + outerClass.getName() + " this$0, java.lang.String p1]") 458 .checkParametersNoVarArgs(); 459 460 helper.getParameterTestHelper(0) 461 .checkName(true /* expectedNameIsPresent */, "this$0") 462 .checkModifiers(32784) // 32784 == Modifier.MANDATED & Modifier.FINAL 463 .checkImplicitAndSynthetic(true, false) 464 .checkGetType(outerClass) 465 .checkGetParameterizedType("class " + outerClass.getName() + ""); 466 467 helper.getParameterTestHelper(1) 468 .checkName(true /* expectedNameIsPresent */, "p1") 469 .checkModifiers(0) 470 .checkImplicitAndSynthetic(false, false) 471 .checkGetType(String.class) 472 .checkGetParameterizedType("class java.lang.String"); 473 } 474 475 @Test testInnerClassGenericParameter()476 public void testInnerClassGenericParameter() throws Exception { 477 Class<?> outerClass = ParameterTest.class; 478 Class<?> innerClass = InnerClass.class; 479 Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass, Function.class); 480 481 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 482 helper.checkStandardParametersBehavior() 483 .checkParametersToString( 484 "[final " + outerClass.getName() + " arg0, " + 485 "java.util.function.Function<java.lang.String, java.lang.Integer> arg1]") 486 .checkParametersNoVarArgs(); 487 488 helper.getParameterTestHelper(0) 489 .checkName(false, "arg0") 490 .checkModifiers(4112) // 4112 == Modifier.SYNTHETIC & Modifier.FINAL 491 .checkImplicitAndSynthetic(false, true) 492 .checkGetType(outerClass) 493 .checkGetParameterizedType("class " + outerClass.getName() + ""); 494 495 helper.getParameterTestHelper(1) 496 .checkName(false, "arg1") 497 .checkModifiers(0) 498 .checkImplicitAndSynthetic(false, false) 499 .checkGetType(Function.class) 500 .checkGetParameterizedType("java.util.function.Function<java.lang.String, java.lang.Integer>"); 501 502 // The non-genericised string above is probably the result of a spec bug due to a mismatch 503 // between the generic signature for the constructor (which suggests a single parameter) 504 // and the actual parameters (which suggests two). In the absence of parameter metadata 505 // to identify the synthetic parameter the code reverts to using non-Signature (type erased) 506 // information. 507 } 508 509 @Test testInnerClassGenericParameter_withMetadata()510 public void testInnerClassGenericParameter_withMetadata() throws Exception { 511 Class<?> outerClass = loadTestOuterClassWithMetadata(); 512 Class<?> innerClass = loadTestInnerClassWithMetadata("InnerClass"); 513 Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass, Function.class); 514 515 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 516 helper.checkStandardParametersBehavior() 517 .checkParametersToString("[final " + outerClass.getName() + " this$0, " 518 + "java.util.function.Function<java.lang.String, java.lang.Integer> p1]") 519 .checkParametersNoVarArgs(); 520 521 helper.getParameterTestHelper(0) 522 .checkName(true /* expectedNameIsPresent */, "this$0") 523 .checkModifiers(32784) // 32784 == Modifier.MANDATED & Modifier.FINAL 524 .checkImplicitAndSynthetic(true, false) 525 .checkGetType(outerClass) 526 .checkGetParameterizedType("class " + outerClass.getName() + ""); 527 528 helper.getParameterTestHelper(1) 529 .checkName(true /* expectedNameIsPresent */, "p1") 530 .checkModifiers(0) 531 .checkImplicitAndSynthetic(false, false) 532 .checkGetType(Function.class) 533 .checkGetParameterizedType( 534 "java.util.function.Function<java.lang.String, java.lang.Integer>"); 535 } 536 537 @SuppressWarnings("unused") 538 enum TestEnum { ONE, TWO } 539 540 /** 541 * Enums are a documented example of a type of class with synthetic constructor parameters and 542 * generated methods. This test may be brittle as it may rely on the compiler's implementation 543 * of enums. 544 */ 545 @Test testEnumConstructor()546 public void testEnumConstructor() throws Exception { 547 Constructor<?> constructor = TestEnum.class.getDeclaredConstructor(String.class, int.class); 548 549 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 550 helper.checkStandardParametersBehavior() 551 .checkParametersToString("[ java.lang.String arg0, int arg1]") 552 .checkParametersNoVarArgs(); 553 554 helper.getParameterTestHelper(0) 555 .checkGetType(String.class) 556 .checkGetParameterizedType("class java.lang.String"); 557 558 helper.getParameterTestHelper(1) 559 .checkGetType(int.class) 560 .checkGetParameterizedType("int"); 561 } 562 563 @Test testEnumConstructor_withMetadata()564 public void testEnumConstructor_withMetadata() throws Exception { 565 Class<?> clazz = loadTestInnerClassWithMetadata("TestEnum"); 566 Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, int.class); 567 568 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 569 helper.checkStandardParametersBehavior() 570 // The extra spaces below are the result of a trivial upstream bug in 571 // Parameter.toString() due to Modifier.toString(int) outputting nothing for 572 // "SYNTHETIC". 573 .checkParametersToString("[ java.lang.String $enum$name, int $enum$ordinal]") 574 .checkParametersNoVarArgs(); 575 576 helper.getParameterTestHelper(0) 577 .checkName(true /* expectedNameIsPresent */, "$enum$name") 578 .checkModifiers(4096) // 4096 == Modifier.SYNTHETIC 579 .checkImplicitAndSynthetic(false, true) 580 .checkGetType(String.class) 581 .checkGetParameterizedType("class java.lang.String"); 582 583 helper.getParameterTestHelper(1) 584 .checkName(true /* expectedNameIsPresent */, "$enum$ordinal") 585 .checkModifiers(4096) // 4096 == Modifier.SYNTHETIC 586 .checkImplicitAndSynthetic(false, true) 587 .checkGetType(int.class) 588 .checkGetParameterizedType("int"); 589 } 590 591 @Test testEnumValueOf()592 public void testEnumValueOf() throws Exception { 593 Method method = TestEnum.class.getDeclaredMethod("valueOf", String.class); 594 595 ExecutableTestHelper helper = new ExecutableTestHelper(method); 596 helper.checkStandardParametersBehavior() 597 .checkParametersToString("[ java.lang.String arg0]") 598 .checkParametersNoVarArgs(); 599 600 helper.getParameterTestHelper(0) 601 .checkName(false, "arg0") 602 .checkModifiers(32768) // 32768 == Modifier.MANDATED 603 .checkImplicitAndSynthetic(true, false) 604 .checkGetType(String.class) 605 .checkGetParameterizedType("class java.lang.String"); 606 } 607 608 @Test testEnumValueOf_withMetadata()609 public void testEnumValueOf_withMetadata() throws Exception { 610 Class<?> clazz = loadTestInnerClassWithMetadata("TestEnum"); 611 Method method = clazz.getDeclaredMethod("valueOf", String.class); 612 613 ExecutableTestHelper helper = new ExecutableTestHelper(method); 614 helper.checkStandardParametersBehavior() 615 // The extra space below are the result of a trivial upstream bug in 616 // Parameter.toString() due to Modifier.toString(int) outputting nothing for 617 // "MANDATED". 618 .checkParametersToString("[ java.lang.String name]") 619 .checkParametersNoVarArgs(); 620 621 helper.getParameterTestHelper(0) 622 .checkName(true /* expectedNameIsPresent */, "name") 623 .checkModifiers(32768) // 32768 == Modifier.MANDATED 624 .checkImplicitAndSynthetic(true, false) 625 .checkGetType(String.class) 626 .checkGetParameterizedType("class java.lang.String"); 627 } 628 629 private static class SingleVarArgs { 630 @SuppressWarnings("unused") SingleVarArgs(String... p0)631 SingleVarArgs(String... p0) {} 632 633 @SuppressWarnings("unused") varArgs(String... p0)634 void varArgs(String... p0) {} 635 } 636 637 @Test testSingleVarArgsConstructor()638 public void testSingleVarArgsConstructor() throws Exception { 639 Constructor<?> constructor = SingleVarArgs.class.getDeclaredConstructor(String[].class); 640 checkSingleVarArgsParameter(constructor); 641 } 642 643 @Test testSingleVarArgsMethod()644 public void testSingleVarArgsMethod() throws Exception { 645 Method method = SingleVarArgs.class.getDeclaredMethod("varArgs", String[].class); 646 checkSingleVarArgsParameter(method); 647 } 648 checkSingleVarArgsParameter(Executable executable)649 private static void checkSingleVarArgsParameter(Executable executable) { 650 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 651 helper.checkStandardParametersBehavior() 652 .checkParametersToString("[java.lang.String... arg0]") 653 .checkParametersMetadataNotAvailable(); 654 655 helper.getParameterTestHelper(0) 656 .checkGetType(String[].class) 657 .checkIsVarArg(true) 658 .checkGetParameterizedType("class [Ljava.lang.String;"); 659 } 660 661 @Test testSingleVarArgsConstructor_withMetadata()662 public void testSingleVarArgsConstructor_withMetadata() throws Exception { 663 Class<?> clazz = loadTestInnerClassWithMetadata("SingleVarArgs"); 664 Constructor<?> constructor = clazz.getDeclaredConstructor(String[].class); 665 checkSingleVarArgsParameter_withMetadata(constructor); 666 } 667 668 @Test testSingleVarArgsMethod_withMetadata()669 public void testSingleVarArgsMethod_withMetadata() throws Exception { 670 Class<?> clazz = loadTestInnerClassWithMetadata("SingleVarArgs"); 671 Method method = clazz.getDeclaredMethod("varArgs", String[].class); 672 checkSingleVarArgsParameter_withMetadata(method); 673 } 674 checkSingleVarArgsParameter_withMetadata(Executable executable)675 private static void checkSingleVarArgsParameter_withMetadata(Executable executable) { 676 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 677 helper.checkStandardParametersBehavior() 678 .checkParametersToString("[java.lang.String... p0]"); 679 680 helper.getParameterTestHelper(0) 681 .checkName(true /* expectedNameIsPresent */, "p0") 682 .checkModifiers(0) 683 .checkImplicitAndSynthetic(false, false) 684 .checkGetType(String[].class) 685 .checkIsVarArg(true) 686 .checkGetParameterizedType("class [Ljava.lang.String;"); 687 } 688 689 private static class MixedVarArgs { 690 @SuppressWarnings("unused") MixedVarArgs(Integer[] p0, String... p1)691 MixedVarArgs(Integer[] p0, String... p1) {} 692 @SuppressWarnings("unused") both(Integer[] p0, String... p1)693 void both(Integer[] p0, String... p1) {} 694 } 695 696 @Test testMixedVarArgsConstructor()697 public void testMixedVarArgsConstructor() throws Exception { 698 Constructor<?> constructor = 699 MixedVarArgs.class.getDeclaredConstructor(Integer[].class, String[].class); 700 checkMixedVarArgsParameter(constructor); 701 } 702 703 @Test testMixedVarArgsMethod()704 public void testMixedVarArgsMethod() throws Exception { 705 Method method = MixedVarArgs.class.getDeclaredMethod("both", Integer[].class, String[].class); 706 checkMixedVarArgsParameter(method); 707 } 708 checkMixedVarArgsParameter(Executable executable)709 private static void checkMixedVarArgsParameter(Executable executable) { 710 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 711 helper.checkStandardParametersBehavior() 712 .checkParametersToString("[java.lang.Integer[] arg0, java.lang.String... arg1]") 713 .checkParametersMetadataNotAvailable(); 714 715 helper.getParameterTestHelper(0) 716 .checkGetType(Integer[].class) 717 .checkIsVarArg(false) 718 .checkGetParameterizedType("class [Ljava.lang.Integer;"); 719 720 helper.getParameterTestHelper(1) 721 .checkGetType(String[].class) 722 .checkIsVarArg(true) 723 .checkGetParameterizedType("class [Ljava.lang.String;"); 724 } 725 726 private static class NonVarArgs { 727 @SuppressWarnings("unused") NonVarArgs(Integer[] p0)728 NonVarArgs(Integer[] p0) {} 729 @SuppressWarnings("unused") notVarArgs(Integer[] p0)730 void notVarArgs(Integer[] p0) {} 731 } 732 733 @Test testNonVarsArgsConstructor()734 public void testNonVarsArgsConstructor() throws Exception { 735 Constructor<?> constructor = NonVarArgs.class.getDeclaredConstructor(Integer[].class); 736 checkNonVarsArgsParameter(constructor); 737 } 738 739 @Test testNonVarsArgsMethod()740 public void testNonVarsArgsMethod() throws Exception { 741 Method method = NonVarArgs.class.getDeclaredMethod("notVarArgs", Integer[].class); 742 checkNonVarsArgsParameter(method); 743 } 744 checkNonVarsArgsParameter(Executable executable)745 private static void checkNonVarsArgsParameter(Executable executable) { 746 ExecutableTestHelper helper = new ExecutableTestHelper(executable); 747 helper.checkStandardParametersBehavior() 748 .checkParametersToString("[java.lang.Integer[] arg0]") 749 .checkParametersMetadataNotAvailable(); 750 751 helper.getParameterTestHelper(0) 752 .checkGetType(Integer[].class) 753 .checkIsVarArg(false) 754 .checkGetParameterizedType("class [Ljava.lang.Integer;"); 755 } 756 757 @Test testAnonymousClassConstructor()758 public void testAnonymousClassConstructor() throws Exception { 759 Class<?> outerClass = ParameterTest.class; 760 Class<?> innerClass = getAnonymousClassWith1ParameterConstructor(); 761 Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass); 762 763 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 764 helper.checkStandardParametersBehavior() 765 .checkParametersToString("[final " + outerClass.getName() + " arg0]") 766 .checkParametersNoVarArgs(); 767 768 helper.getParameterTestHelper(0) 769 .checkName(false, "arg0") 770 .checkModifiers(32784) // 32784 == Modifier.MANDATED & Modifier.FINAL 771 .checkImplicitAndSynthetic(true, false) 772 .checkGetType(outerClass) 773 .checkGetParameterizedType("class " + outerClass.getName() + ""); 774 } 775 getAnonymousClassWith1ParameterConstructor()776 private Class<?> getAnonymousClassWith1ParameterConstructor() { 777 // Deliberately not implemented with a lambda. Do not refactor. 778 Callable<String> anonymousClassObject = new Callable<String>() { 779 @Override 780 public String call() throws Exception { 781 return ParameterTest.this.outerClassMethod(); 782 } 783 }; 784 return anonymousClassObject.getClass(); 785 } 786 787 @Test testAnonymousClassConstructor_withMetadata()788 public void testAnonymousClassConstructor_withMetadata() throws Exception { 789 Class<?> outerClass = loadTestOuterClassWithMetadata(); 790 Object outer = outerClass.newInstance(); 791 Class<?> innerClass = (Class<?>) outerClass.getDeclaredMethod( 792 "getAnonymousClassWith1ParameterConstructor").invoke(outer); 793 Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass); 794 795 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 796 helper.checkStandardParametersBehavior() 797 .checkParametersToString("[final " + outerClass.getName() + " this$0]") 798 .checkParametersNoVarArgs(); 799 800 helper.getParameterTestHelper(0) 801 .checkName(true /* expectedNameIsPresent */, "this$0") 802 .checkModifiers(32784) // 32784 == Modifier.MANDATED & Modifier.FINAL 803 .checkImplicitAndSynthetic(true, false) 804 .checkGetType(outerClass) 805 .checkGetParameterizedType("class " + outerClass.getName() + ""); 806 } 807 808 @Test testMethodClassConstructor()809 public void testMethodClassConstructor() throws Exception { 810 Class<?> outerClass = ParameterTest.class; 811 Class<?> innerClass = getMethodClassWith1ImplicitParameterConstructor(); 812 Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass); 813 814 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 815 helper.checkStandardParametersBehavior() 816 .checkParametersToString("[final " + outerClass.getName() + " arg0]") 817 .checkParametersNoVarArgs(); 818 819 helper.getParameterTestHelper(0) 820 .checkName(false, "arg0") 821 .checkModifiers(32784) // 32784 == Modifier.MANDATED & Modifier.FINAL 822 .checkImplicitAndSynthetic(true, false) 823 .checkGetType(outerClass) 824 .checkGetParameterizedType("class " + outerClass.getName() + ""); 825 } 826 getMethodClassWith1ImplicitParameterConstructor()827 private Class<?> getMethodClassWith1ImplicitParameterConstructor() { 828 class MethodClass { 829 MethodClass() { 830 ParameterTest.this.outerClassMethod(); 831 } 832 } 833 return MethodClass.class; 834 } 835 836 @Test testMethodClassConstructor_withMetadata()837 public void testMethodClassConstructor_withMetadata() throws Exception { 838 Class<?> outerClass = loadTestOuterClassWithMetadata(); 839 Object outer = outerClass.newInstance(); 840 Class<?> innerClass = (Class<?>) outerClass.getDeclaredMethod( 841 "getMethodClassWith1ImplicitParameterConstructor").invoke(outer); 842 Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass); 843 844 ExecutableTestHelper helper = new ExecutableTestHelper(constructor); 845 helper.checkStandardParametersBehavior() 846 .checkParametersToString("[final " + outerClass.getName() + " this$0]") 847 .checkParametersNoVarArgs(); 848 849 helper.getParameterTestHelper(0) 850 .checkName(true /* expectedNameIsPresent */, "this$0") 851 .checkModifiers(32784) // 32784 == Modifier.MANDATED & Modifier.FINAL 852 .checkImplicitAndSynthetic(true, false) 853 .checkGetType(outerClass) 854 .checkGetParameterizedType("class " + outerClass.getName() + ""); 855 } 856 857 private static class NonIdenticalParameters { 858 @SuppressWarnings("unused") method0(String p0)859 void method0(String p0) {} 860 @SuppressWarnings("unused") method1(String p0)861 void method1(String p0) {} 862 } 863 864 @Test testEquals_checksExecutable()865 public void testEquals_checksExecutable() throws Exception { 866 Method method0 = NonIdenticalParameters.class.getDeclaredMethod("method0", String.class); 867 Method method1 = NonIdenticalParameters.class.getDeclaredMethod("method1", String.class); 868 Parameter method0P0 = method0.getParameters()[0]; 869 Parameter method1P0 = method1.getParameters()[0]; 870 assertFalse(method0P0.equals(method1P0)); 871 assertFalse(method1P0.equals(method0P0)); 872 assertTrue(method0P0.equals(method0P0)); 873 } 874 875 @Test testManyParameters_withMetadata()876 public void testManyParameters_withMetadata() throws Exception { 877 int expectedParameterCount = 300; 878 Class<?>[] parameterTypes = new Class[expectedParameterCount]; 879 Arrays.fill(parameterTypes, int.class); 880 Method method = getMetadataVariationsMethod("manyParameters", parameterTypes); 881 Parameter[] parameters = method.getParameters(); 882 assertEquals(expectedParameterCount, parameters.length); 883 884 NumberFormat format = NumberFormat.getIntegerInstance(); 885 format.setMinimumIntegerDigits(3); 886 for (int i = 0; i < parameters.length; i++) { 887 assertEquals(true, parameters[i].isNamePresent()); 888 assertEquals(Modifier.FINAL, parameters[i].getModifiers()); 889 assertEquals("a" + format.format(i), parameters[i].getName()); 890 } 891 } 892 893 @Test testEmptyMethodParametersAnnotation_withMetadata()894 public void testEmptyMethodParametersAnnotation_withMetadata() throws Exception { 895 Method method = getMetadataVariationsMethod("emptyMethodParametersAnnotation"); 896 assertEquals(0, method.getParameters().length); 897 } 898 899 @Test testTooManyAccessFlags_withMetadata()900 public void testTooManyAccessFlags_withMetadata() throws Exception { 901 Method method = getMetadataVariationsMethod("tooManyAccessFlags", String.class); 902 checkGetParametersThrowsMalformedParametersException(method); 903 } 904 905 @Test testTooFewAccessFlags_withMetadata()906 public void testTooFewAccessFlags_withMetadata() throws Exception { 907 Method method = getMetadataVariationsMethod( 908 "tooFewAccessFlags", String.class, String.class); 909 checkGetParametersThrowsMalformedParametersException(method); 910 } 911 912 @Test testTooManyNames_withMetadata()913 public void testTooManyNames_withMetadata() throws Exception { 914 Method method = getMetadataVariationsMethod("tooManyNames", String.class); 915 checkGetParametersThrowsMalformedParametersException(method); 916 } 917 918 @Test testTooFewNames_withMetadata()919 public void testTooFewNames_withMetadata() throws Exception { 920 Method method = getMetadataVariationsMethod("tooFewNames", String.class, String.class); 921 checkGetParametersThrowsMalformedParametersException(method); 922 } 923 924 @Test testTooManyBoth_withMetadata()925 public void testTooManyBoth_withMetadata() throws Exception { 926 Method method = getMetadataVariationsMethod("tooManyBoth", String.class); 927 checkGetParametersThrowsMalformedParametersException(method); 928 } 929 930 @Test testTooFewBoth_withMetadata()931 public void testTooFewBoth_withMetadata() throws Exception { 932 Method method = getMetadataVariationsMethod("tooFewBoth", String.class, String.class); 933 checkGetParametersThrowsMalformedParametersException(method); 934 } 935 936 @Test testNullName_withMetadata()937 public void testNullName_withMetadata() throws Exception { 938 Method method = getMetadataVariationsMethod("nullName", String.class); 939 Parameter parameter0 = method.getParameters()[0]; 940 assertEquals("arg0", parameter0.getName()); 941 assertEquals(Modifier.FINAL, parameter0.getModifiers()); 942 } 943 944 @Test testEmptyName_withMetadata()945 public void testEmptyName_withMetadata() throws Exception { 946 Method method = getMetadataVariationsMethod("emptyName", String.class); 947 checkGetParametersThrowsMalformedParametersException(method); 948 } 949 950 @Test testNameWithSemicolon_withMetadata()951 public void testNameWithSemicolon_withMetadata() throws Exception { 952 Method method = getMetadataVariationsMethod("nameWithSemicolon", String.class); 953 checkGetParametersThrowsMalformedParametersException(method); 954 } 955 956 @Test testNameWithSlash_withMetadata()957 public void testNameWithSlash_withMetadata() throws Exception { 958 Method method = getMetadataVariationsMethod("nameWithSlash", String.class); 959 checkGetParametersThrowsMalformedParametersException(method); 960 } 961 962 @Test testNameWithPeriod_withMetadata()963 public void testNameWithPeriod_withMetadata() throws Exception { 964 Method method = getMetadataVariationsMethod("nameWithPeriod", String.class); 965 checkGetParametersThrowsMalformedParametersException(method); 966 } 967 968 @Test testNameWithOpenSquareBracket_withMetadata()969 public void testNameWithOpenSquareBracket_withMetadata() throws Exception { 970 Method method = getMetadataVariationsMethod("nameWithOpenSquareBracket", String.class); 971 checkGetParametersThrowsMalformedParametersException(method); 972 } 973 974 @Test testBadAccessModifier_withMetadata()975 public void testBadAccessModifier_withMetadata() throws Exception { 976 Method method = getMetadataVariationsMethod("badAccessModifier", String.class); 977 checkGetParametersThrowsMalformedParametersException(method); 978 } 979 980 @Test testBadlyFormedAnnotation()981 public void testBadlyFormedAnnotation() throws Exception { 982 Method method = getMetadataVariationsMethod("badlyFormedAnnotation", String.class); 983 // Badly formed annotations are treated as if the annotation is entirely absent. 984 Parameter parameter0 = method.getParameters()[0]; 985 assertFalse(parameter0.isNamePresent()); 986 } 987 988 /** A non-static method that exists to be called by inner classes, lambdas, etc. */ outerClassMethod()989 private String outerClassMethod() { 990 return "Howdy"; 991 } 992 993 private static class ExecutableTestHelper { 994 private final Executable executable; 995 ExecutableTestHelper(Executable executable)996 ExecutableTestHelper(Executable executable) { 997 this.executable = executable; 998 } 999 1000 @DependsOnParameterMetadata checkParametersToString(String expectedString)1001 ExecutableTestHelper checkParametersToString(String expectedString) { 1002 assertEquals(expectedString, Arrays.toString(executable.getParameters())); 1003 return this; 1004 } 1005 1006 /** 1007 * Combines checks that should be true of any result from 1008 * {@link Executable#getParameters()} 1009 */ checkStandardParametersBehavior()1010 ExecutableTestHelper checkStandardParametersBehavior() { 1011 return checkGetParametersClonesArray() 1012 .checkParametersGetDeclaringExecutable() 1013 .checkParametersEquals() 1014 .checkParametersHashcode(); 1015 } 1016 checkParametersGetDeclaringExecutable()1017 ExecutableTestHelper checkParametersGetDeclaringExecutable() { 1018 for (Parameter p : executable.getParameters()) { 1019 assertSame(executable, p.getDeclaringExecutable()); 1020 } 1021 return this; 1022 } 1023 checkGetParametersClonesArray()1024 ExecutableTestHelper checkGetParametersClonesArray() { 1025 Parameter[] parameters1 = executable.getParameters(); 1026 Parameter[] parameters2 = executable.getParameters(); 1027 assertNotSame(parameters1, parameters2); 1028 1029 assertEquals(parameters1.length, parameters2.length); 1030 for (int i = 0; i < parameters1.length; i++) { 1031 assertSame(parameters1[i], parameters2[i]); 1032 } 1033 return this; 1034 } 1035 checkParametersEquals()1036 ExecutableTestHelper checkParametersEquals() { 1037 Parameter[] parameters = executable.getParameters(); 1038 for (int i = 0; i < parameters.length; i++) { 1039 assertEquals(parameters[i], parameters[i]); 1040 if (i > 0) { 1041 assertFalse(parameters[0].equals(parameters[i])); 1042 assertFalse(parameters[i].equals(parameters[0])); 1043 } 1044 } 1045 return this; 1046 } 1047 checkParametersHashcode()1048 ExecutableTestHelper checkParametersHashcode() { 1049 for (Parameter parameter : executable.getParameters()) { 1050 // Not much to assert. Just call the method and check it is consistent. 1051 assertEquals(parameter.hashCode(), parameter.hashCode()); 1052 } 1053 return this; 1054 } 1055 1056 @DependsOnParameterMetadata checkParametersMetadataNotAvailable()1057 ExecutableTestHelper checkParametersMetadataNotAvailable() { 1058 ParameterTestHelper[] parameterTestHelpers = getParameterTestHelpers(); 1059 for (int i = 0; i < parameterTestHelpers.length; i++) { 1060 ParameterTestHelper parameterTestHelper = parameterTestHelpers[i]; 1061 parameterTestHelper.checkName(false, "arg" + i) 1062 .checkImplicitAndSynthetic(false, false) 1063 .checkModifiers(0); 1064 } 1065 return this; 1066 } 1067 1068 /** 1069 * Checks that non of the parameters return {@code true} for {@link Parameter#isVarArgs()}. 1070 */ checkParametersNoVarArgs()1071 ExecutableTestHelper checkParametersNoVarArgs() { 1072 for (ParameterTestHelper parameterTestHelper : getParameterTestHelpers()) { 1073 parameterTestHelper.checkIsVarArg(false); 1074 } 1075 return this; 1076 } 1077 getParameterTestHelper(int index)1078 ParameterTestHelper getParameterTestHelper(int index) { 1079 return new ParameterTestHelper(executable.getParameters()[index]); 1080 } 1081 getParameterTestHelpers()1082 private ParameterTestHelper[] getParameterTestHelpers() { 1083 final int parameterCount = executable.getParameterCount(); 1084 ParameterTestHelper[] parameterTestHelpers = new ParameterTestHelper[parameterCount]; 1085 for (int i = 0; i < parameterCount; i++) { 1086 parameterTestHelpers[i] = getParameterTestHelper(i); 1087 } 1088 return parameterTestHelpers; 1089 } 1090 1091 private static class ParameterTestHelper { 1092 private final Parameter parameter; 1093 ParameterTestHelper(Parameter parameter)1094 ParameterTestHelper(Parameter parameter) { 1095 this.parameter = parameter; 1096 } 1097 checkGetType(Class<?> expectedType)1098 ParameterTestHelper checkGetType(Class<?> expectedType) { 1099 assertEquals(expectedType, parameter.getType()); 1100 return this; 1101 } 1102 1103 @DependsOnParameterMetadata checkName(boolean expectedIsNamePresent, String expectedName)1104 ParameterTestHelper checkName(boolean expectedIsNamePresent, String expectedName) { 1105 assertEquals(expectedIsNamePresent, parameter.isNamePresent()); 1106 assertEquals(expectedName, parameter.getName()); 1107 return this; 1108 } 1109 1110 @DependsOnParameterMetadata checkModifiers(int expectedModifiers)1111 ParameterTestHelper checkModifiers(int expectedModifiers) { 1112 assertEquals(expectedModifiers, parameter.getModifiers()); 1113 return this; 1114 } 1115 checkGetParameterizedType(String expectedParameterizedTypeString)1116 ParameterTestHelper checkGetParameterizedType(String expectedParameterizedTypeString) { 1117 assertEquals( 1118 expectedParameterizedTypeString, 1119 parameter.getParameterizedType().toString()); 1120 return this; 1121 } 1122 1123 @DependsOnParameterMetadata checkImplicitAndSynthetic( boolean expectedIsImplicit, boolean expectedIsSynthetic)1124 ParameterTestHelper checkImplicitAndSynthetic( 1125 boolean expectedIsImplicit, boolean expectedIsSynthetic) { 1126 assertEquals(expectedIsImplicit, parameter.isImplicit()); 1127 assertEquals(expectedIsSynthetic, parameter.isSynthetic()); 1128 return this; 1129 } 1130 checkIsVarArg(boolean expectedIsVarArg)1131 ParameterTestHelper checkIsVarArg(boolean expectedIsVarArg) { 1132 assertEquals(expectedIsVarArg, parameter.isVarArgs()); 1133 return this; 1134 } 1135 } 1136 } 1137 createClassLoaderForResource(File destDir, String resourcePath)1138 private static ClassLoader createClassLoaderForResource(File destDir, String resourcePath) 1139 throws Exception { 1140 String fileName = new File(resourcePath).getName(); 1141 File dexOrJarFile = new File(destDir, fileName); 1142 copyResource(resourcePath, dexOrJarFile); 1143 assertTrue(dexOrJarFile.setReadOnly()); 1144 return new PathClassLoader( 1145 dexOrJarFile.getAbsolutePath(), ClassLoader.getSystemClassLoader()); 1146 } 1147 1148 /** 1149 * Copy a resource in the libcore/java/lang/reflect/parameter/ resource path to the indicated 1150 * target file. 1151 */ copyResource(String resourcePath, File destination)1152 private static void copyResource(String resourcePath, File destination) throws Exception { 1153 assertFalse(destination.exists()); 1154 ClassLoader classLoader = ParameterTest.class.getClassLoader(); 1155 assertNotNull(classLoader); 1156 1157 try (InputStream in = classLoader.getResourceAsStream(resourcePath); 1158 FileOutputStream out = new FileOutputStream(destination)) { 1159 if (in == null) { 1160 throw new IllegalStateException("Resource not found: " + resourcePath); 1161 } 1162 Streams.copy(in, out); 1163 } 1164 } 1165 1166 /** 1167 * Loads an inner class from the ParameterMetadataTestClasses class defined in a separate dex 1168 * file. See src/test/java/libcore/java/lang/reflect/parameter/ for the associated source code. 1169 */ loadTestInnerClassWithMetadata(String name)1170 private Class<?> loadTestInnerClassWithMetadata(String name) throws Exception { 1171 return classesWithMetadataClassLoader.loadClass( 1172 "libcore.java.lang.reflect.parameter.ParameterMetadataTestClasses$" + name); 1173 } 1174 1175 /** 1176 * Loads the ParameterMetadataTestClasses class defined in a separate dex file. 1177 * See src/test/java/libcore/java/lang/reflect/parameter/ for the associated source code. 1178 */ loadTestOuterClassWithMetadata()1179 private Class<?> loadTestOuterClassWithMetadata() throws Exception { 1180 return classesWithMetadataClassLoader.loadClass( 1181 "libcore.java.lang.reflect.parameter.ParameterMetadataTestClasses"); 1182 } 1183 1184 /** 1185 * Loads a method from the MetadataVariations class defined in a separate dex file. See 1186 * src/test/java/libcore/java/lang/reflect/parameter/ for the associated source code. 1187 */ getMetadataVariationsMethod(String methodName, Class<?>... parameterTypes)1188 private Method getMetadataVariationsMethod(String methodName, Class<?>... parameterTypes) 1189 throws Exception { 1190 Class<?> metadataVariationsClass = metadataVariationsClassLoader.loadClass( 1191 "libcore.java.lang.reflect.parameter.MetadataVariations"); 1192 return metadataVariationsClass.getDeclaredMethod(methodName, parameterTypes); 1193 } 1194 checkGetParametersThrowsMalformedParametersException(Method method)1195 private static void checkGetParametersThrowsMalformedParametersException(Method method) { 1196 try { 1197 method.getParameters(); 1198 fail(); 1199 } catch (MalformedParametersException expected) {} 1200 } 1201 } 1202