8336777: BufferedMethodBuilder not initialized with static flag
Reviewed-by: asotona
This commit is contained in:
parent
c25c4896ad
commit
3ade2b6114
src/java.base/share/classes/jdk/internal/classfile/impl
BufferedMethodBuilder.javaChainedClassBuilder.javaDirectMethodBuilder.javaMethodInfo.javaTerminalMethodBuilder.java
test/jdk/jdk/classfile
@ -25,6 +25,7 @@
|
||||
package jdk.internal.classfile.impl;
|
||||
|
||||
import java.lang.constant.MethodTypeDesc;
|
||||
import java.lang.reflect.AccessFlag;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@ -44,7 +45,7 @@ import java.lang.classfile.MethodModel;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
public final class BufferedMethodBuilder
|
||||
implements TerminalMethodBuilder, MethodInfo {
|
||||
implements TerminalMethodBuilder {
|
||||
private final List<MethodElement> elements;
|
||||
private final SplitConstantPool constantPool;
|
||||
private final ClassFileImpl context;
|
||||
@ -59,23 +60,32 @@ public final class BufferedMethodBuilder
|
||||
ClassFileImpl context,
|
||||
Utf8Entry nameInfo,
|
||||
Utf8Entry typeInfo,
|
||||
int flags,
|
||||
MethodModel original) {
|
||||
this.elements = new ArrayList<>();
|
||||
this.constantPool = constantPool;
|
||||
this.context = context;
|
||||
this.name = nameInfo;
|
||||
this.desc = typeInfo;
|
||||
this.flags = AccessFlags.ofMethod();
|
||||
this.flags = AccessFlags.ofMethod(flags);
|
||||
this.original = original;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodBuilder with(MethodElement element) {
|
||||
elements.add(element);
|
||||
if (element instanceof AccessFlags f) this.flags = f;
|
||||
if (element instanceof AccessFlags f) this.flags = checkFlags(f);
|
||||
return this;
|
||||
}
|
||||
|
||||
private AccessFlags checkFlags(AccessFlags updated) {
|
||||
boolean wasStatic = updated.has(AccessFlag.STATIC);
|
||||
boolean isStatic = flags.has(AccessFlag.STATIC);
|
||||
if (wasStatic != isStatic)
|
||||
throw new IllegalArgumentException("Cannot change ACC_STATIC flag of method");
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstantPoolBuilder constantPool() {
|
||||
return constantPool;
|
||||
|
@ -79,7 +79,7 @@ public final class ChainedClassBuilder
|
||||
public ClassBuilder withMethod(Utf8Entry name, Utf8Entry descriptor, int flags,
|
||||
Consumer<? super MethodBuilder> handler) {
|
||||
consumer.accept(new BufferedMethodBuilder(terminal.constantPool, terminal.context,
|
||||
name, descriptor, null)
|
||||
name, descriptor, flags, null)
|
||||
.run(handler)
|
||||
.toModel());
|
||||
return this;
|
||||
@ -88,7 +88,7 @@ public final class ChainedClassBuilder
|
||||
@Override
|
||||
public ClassBuilder transformMethod(MethodModel method, MethodTransform transform) {
|
||||
BufferedMethodBuilder builder = new BufferedMethodBuilder(terminal.constantPool, terminal.context,
|
||||
method.methodName(), method.methodType(), method);
|
||||
method.methodName(), method.methodType(), method.flags().flagsMask(), method);
|
||||
builder.transform(method, transform);
|
||||
consumer.accept(builder.toModel());
|
||||
return this;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, 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
|
||||
@ -42,7 +42,7 @@ import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
public final class DirectMethodBuilder
|
||||
extends AbstractDirectBuilder<MethodModel>
|
||||
implements TerminalMethodBuilder, WritableElement<MethodModel>, MethodInfo {
|
||||
implements TerminalMethodBuilder, WritableElement<MethodModel> {
|
||||
|
||||
final Utf8Entry name;
|
||||
final Utf8Entry desc;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, 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
|
||||
@ -29,7 +29,8 @@ import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
import static java.lang.classfile.ClassFile.ACC_STATIC;
|
||||
|
||||
public interface MethodInfo {
|
||||
public sealed interface MethodInfo
|
||||
permits MethodImpl, TerminalMethodBuilder, BufferedMethodBuilder.Model {
|
||||
Utf8Entry methodName();
|
||||
Utf8Entry methodType();
|
||||
MethodTypeDesc methodTypeSymbol();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, 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
|
||||
@ -28,7 +28,7 @@ import java.lang.classfile.CodeModel;
|
||||
import java.lang.classfile.MethodBuilder;
|
||||
|
||||
public sealed interface TerminalMethodBuilder
|
||||
extends MethodBuilder
|
||||
extends MethodBuilder, MethodInfo
|
||||
permits BufferedMethodBuilder, DirectMethodBuilder {
|
||||
BufferedCodeBuilder bufferedCodeBuilder(CodeModel original);
|
||||
}
|
||||
|
80
test/jdk/jdk/classfile/MethodBuilderStaticFlagTest.java
Normal file
80
test/jdk/jdk/classfile/MethodBuilderStaticFlagTest.java
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import jdk.internal.classfile.impl.ChainedClassBuilder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.classfile.ClassBuilder;
|
||||
import java.lang.classfile.ClassElement;
|
||||
import java.lang.classfile.ClassFile;
|
||||
import java.lang.classfile.ClassTransform;
|
||||
import java.lang.constant.ClassDesc;
|
||||
|
||||
import static java.lang.classfile.ClassFile.ACC_PUBLIC;
|
||||
import static java.lang.classfile.ClassFile.ACC_STATIC;
|
||||
import static java.lang.constant.ConstantDescs.MTD_void;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8336777
|
||||
* @summary Testing MethodBuilder correctly rejecting resetting the static
|
||||
* access flag.
|
||||
* @run junit MethodBuilderStaticFlagTest
|
||||
*/
|
||||
class MethodBuilderStaticFlagTest {
|
||||
|
||||
void testClassBuilder(ClassBuilder clb) {
|
||||
clb.withMethod("staticToStatic", MTD_void, ACC_STATIC, mb -> mb.withFlags(ACC_PUBLIC | ACC_STATIC));
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
clb.withMethod("staticToInstance", MTD_void, ACC_STATIC, mb -> mb.withFlags(ACC_PUBLIC)));
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
clb.withMethod("instanceToStatic", MTD_void, 0, mb -> mb.withFlags(ACC_PUBLIC | ACC_STATIC)));
|
||||
clb.withMethod("instanceToInstance", MTD_void, 0, mb -> mb.withFlags(ACC_PUBLIC));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDirectBuilder() {
|
||||
ClassFile.of().build(ClassDesc.of("C1"), this::testClassBuilder);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBufferedBuilder() {
|
||||
var cf = ClassFile.of();
|
||||
var bytes = cf.build(ClassDesc.of("C2"), _ -> {});
|
||||
var cm = cf.parse(bytes);
|
||||
|
||||
cf.transformClass(cm, new ClassTransform() {
|
||||
@Override
|
||||
public void accept(ClassBuilder builder, ClassElement element) {
|
||||
builder.with(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void atEnd(ClassBuilder clb) {
|
||||
assertInstanceOf(ChainedClassBuilder.class, clb);
|
||||
testClassBuilder(clb);
|
||||
}
|
||||
}.andThen(ClassBuilder::with));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user