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