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