diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/BufferedFieldBuilder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/BufferedFieldBuilder.java index 598ae3dc58f5d..b2792f2627f81 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/BufferedFieldBuilder.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/BufferedFieldBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,6 +107,16 @@ public Utf8Entry fieldType() { return desc; } + @Override + public void writeTo(DirectClassBuilder builder) { + builder.withField(name, desc, new Consumer<FieldBuilder>() { + @Override + public void accept(FieldBuilder fieldBuilder) { + elements.forEach(fieldBuilder); + } + }); + } + @Override public void writeTo(BufWriter buf) { DirectFieldBuilder fb = new DirectFieldBuilder(constantPool, name, desc, null); diff --git a/test/jdk/jdk/classfile/ClassBuildingTest.java b/test/jdk/jdk/classfile/ClassBuildingTest.java new file mode 100644 index 0000000000000..f774ac97608a2 --- /dev/null +++ b/test/jdk/jdk/classfile/ClassBuildingTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8304937 + * @compile -parameters ClassBuildingTest.java + * @summary Ensure that class transform chaining works. + * @run junit ClassBuildingTest + */ + +import jdk.internal.classfile.ClassModel; +import jdk.internal.classfile.ClassTransform; +import jdk.internal.classfile.Classfile; +import jdk.internal.classfile.MethodTransform; +import jdk.internal.classfile.attribute.MethodParametersAttribute; +import jdk.internal.classfile.attribute.SignatureAttribute; +import jdk.internal.classfile.components.ClassRemapper; +import org.junit.jupiter.api.Test; + +import java.lang.constant.ClassDesc; +import java.lang.invoke.MethodHandles; +import java.util.Comparator; +import java.util.Map; +import java.util.Objects; + +public class ClassBuildingTest { + @Test + public void test() throws Throwable { + ClassModel cm; + try (var in = ClassBuildingTest.class.getResourceAsStream("/Outer$1Local.class")) { + cm = Classfile.parse(Objects.requireNonNull(in).readAllBytes()); + } + + ClassTransform transform = ClassRemapper.of(Map.of(ClassDesc.of("Outer"), ClassDesc.of("Router"))); + transform = transform.andThen(ClassTransform.transformingMethods(MethodTransform.dropping(me + -> me instanceof MethodParametersAttribute))); + transform = transform.andThen(ClassTransform.transformingMethods(MethodTransform.dropping(me + -> me instanceof SignatureAttribute))); + + MethodHandles.lookup().defineClass(cm.transform(transform)); + } +} + +class Outer { + void method(int p) { + class Local<V> { + Local(V value, int q, Comparator<Integer> p2) { + System.out.println(p + q); + } + } + } +}