|
1 | 1 | /* |
2 | | - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
|
23 | 23 |
|
24 | 24 | /* |
25 | 25 | * @test |
26 | | - * @bug 8335935 8336588 |
| 26 | + * @bug 8335935 8336588 8372047 |
27 | 27 | * @summary Testing ClassFile transformations. |
28 | 28 | * @run junit TransformTests |
29 | 29 | */ |
30 | 30 |
|
31 | | -import java.lang.classfile.ClassBuilder; |
32 | | -import java.lang.classfile.ClassElement; |
33 | | -import java.lang.classfile.ClassFile; |
34 | | -import java.lang.classfile.ClassModel; |
35 | | -import java.lang.classfile.ClassTransform; |
36 | | -import java.lang.classfile.CodeBuilder; |
37 | | -import java.lang.classfile.CodeElement; |
38 | | -import java.lang.classfile.CodeModel; |
39 | | -import java.lang.classfile.CodeTransform; |
40 | | -import java.lang.classfile.FieldModel; |
41 | | -import java.lang.classfile.FieldTransform; |
42 | | -import java.lang.classfile.Label; |
43 | | -import java.lang.classfile.MethodModel; |
44 | | -import java.lang.classfile.MethodTransform; |
| 31 | +import java.lang.classfile.*; |
| 32 | +import java.lang.classfile.attribute.AnnotationDefaultAttribute; |
| 33 | +import java.lang.classfile.attribute.ConstantValueAttribute; |
| 34 | +import java.lang.classfile.attribute.SourceDebugExtensionAttribute; |
45 | 35 | import java.lang.classfile.instruction.BranchInstruction; |
46 | 36 | import java.lang.classfile.instruction.ConstantInstruction; |
47 | 37 | import java.lang.classfile.instruction.LabelTarget; |
|
54 | 44 | import java.nio.file.Paths; |
55 | 45 | import java.util.HashSet; |
56 | 46 | import java.util.Set; |
| 47 | +import java.util.concurrent.atomic.AtomicBoolean; |
57 | 48 |
|
58 | 49 | import helpers.ByteArrayClassLoader; |
| 50 | +import jdk.internal.classfile.impl.TransformImpl; |
59 | 51 | import org.junit.jupiter.api.Test; |
60 | 52 |
|
61 | 53 | import static java.lang.classfile.ClassFile.*; |
@@ -334,4 +326,54 @@ static public String foo() { |
334 | 326 | return "foo"; |
335 | 327 | } |
336 | 328 | } |
| 329 | + |
| 330 | + @Test |
| 331 | + void testFilteringTransformChaining() { |
| 332 | + var cf = ClassFile.of(); |
| 333 | + var clazz = cf.parse(cf.build(ClassDesc.of("Test"), clb -> clb |
| 334 | + .withField("one", CD_int, fb -> fb.with(ConstantValueAttribute.of(1))) |
| 335 | + .withField("two", CD_int, fb -> fb.with(ConstantValueAttribute.of(2))) |
| 336 | + .withMethod("one", MTD_void, 0, mb -> mb.with(AnnotationDefaultAttribute.of(AnnotationValue.ofInt(1))).withCode(CodeBuilder::return_)) |
| 337 | + .withMethod("two", MTD_void, 0, mb -> mb.with(AnnotationDefaultAttribute.of(AnnotationValue.ofInt(2))).withCode(CodeBuilder::return_)))); |
| 338 | + |
| 339 | + AtomicBoolean oneFieldCalled = new AtomicBoolean(false); |
| 340 | + var oneFieldTransform = new TransformImpl.ClassFieldTransform((fb, fe) -> { |
| 341 | + if (fe instanceof ConstantValueAttribute cv) { |
| 342 | + assertEquals(1, ((Integer) cv.constant().constantValue()), "Should only transform one"); |
| 343 | + } |
| 344 | + oneFieldCalled.set(true); |
| 345 | + fb.with(fe); |
| 346 | + }, fm -> fm.fieldName().equalsString("one")); |
| 347 | + AtomicBoolean twoFieldCalled = new AtomicBoolean(false); |
| 348 | + var twoFieldTransform = new TransformImpl.ClassFieldTransform((fb, fe) -> { |
| 349 | + if (fe instanceof ConstantValueAttribute cv) { |
| 350 | + assertEquals(2, ((Integer) cv.constant().constantValue()), "Should only transform two"); |
| 351 | + } |
| 352 | + twoFieldCalled.set(true); |
| 353 | + fb.with(fe); |
| 354 | + }, fm -> fm.fieldName().equalsString("two")); |
| 355 | + cf.transformClass(clazz, oneFieldTransform.andThen(twoFieldTransform)); |
| 356 | + assertTrue(oneFieldCalled.get(), "Field one not transformed"); |
| 357 | + assertTrue(twoFieldCalled.get(), "Field two not transformed"); |
| 358 | + |
| 359 | + AtomicBoolean oneMethodCalled = new AtomicBoolean(false); |
| 360 | + var oneMethodTransform = ClassTransform.transformingMethods(mm -> mm.methodName().equalsString("one"), (mb, me) -> { |
| 361 | + if (me instanceof AnnotationDefaultAttribute ada) { |
| 362 | + assertEquals(1, ((AnnotationValue.OfInt) ada.defaultValue()).intValue(), "Should only transform one"); |
| 363 | + } |
| 364 | + oneMethodCalled.set(true); |
| 365 | + mb.with(me); |
| 366 | + }); |
| 367 | + AtomicBoolean twoMethodCalled = new AtomicBoolean(false); |
| 368 | + var twoMethodTransform = ClassTransform.transformingMethods(mm -> mm.methodName().equalsString("two"), (mb, me) -> { |
| 369 | + if (me instanceof AnnotationDefaultAttribute ada) { |
| 370 | + assertEquals(2, ((AnnotationValue.OfInt) ada.defaultValue()).intValue(), "Should only transform two"); |
| 371 | + } |
| 372 | + twoMethodCalled.set(true); |
| 373 | + mb.with(me); |
| 374 | + }); |
| 375 | + cf.transformClass(clazz, oneMethodTransform.andThen(twoMethodTransform)); |
| 376 | + assertTrue(oneMethodCalled.get(), "Method one not transformed"); |
| 377 | + assertTrue(twoMethodCalled.get(), "Method two not transformed"); |
| 378 | + } |
337 | 379 | } |
0 commit comments