< prev index next > test/jdk/jdk/classfile/AccessFlagsTest.java
Print this page
/*
! * 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
/*
! * Copyright (c) 2022, 2026, 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.
*/
/*
* @test
* @summary Testing ClassFile AccessFlags.
* @run junit AccessFlagsTest
*/
import java.lang.classfile.ClassFile;
import java.lang.constant.ClassDesc;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
- import java.util.function.Function;
- import java.util.function.IntFunction;
import java.lang.reflect.AccessFlag;
import java.lang.classfile.AccessFlags;
import static java.lang.classfile.ClassFile.ACC_STATIC;
import static java.lang.constant.ConstantDescs.CD_int;
import static java.lang.constant.ConstantDescs.MTD_void;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.ParameterizedTest;
class AccessFlagsTest {
@ParameterizedTest
@EnumSource(names = { "CLASS", "METHOD", "FIELD" })
void testRandomAccessFlagsConverions(AccessFlag.Location ctx) {
! IntFunction<AccessFlags> intFactory = switch (ctx) {
! case CLASS -> v -> {
! var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb -> clb.withFlags(v));
return ClassFile.of().parse(bytes).flags();
};
! case METHOD -> v -> {
! var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb ->
! clb.withMethod("test", MTD_void, v & ACC_STATIC, mb -> mb.withFlags(v)));
return ClassFile.of().parse(bytes).methods().getFirst().flags();
};
! case FIELD -> v -> {
! var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb ->
! clb.withField("test", CD_int, fb -> fb.withFlags(v)));
return ClassFile.of().parse(bytes).fields().getFirst().flags();
};
! default -> null;
};
! Function<AccessFlag[], AccessFlags> flagsFactory = switch (ctx) {
! case CLASS -> v -> {
! var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb -> clb.withFlags(v));
return ClassFile.of().parse(bytes).flags();
};
! case METHOD -> v -> {
boolean hasStatic = Arrays.stream(v).anyMatch(f -> f == AccessFlag.STATIC);
! var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb ->
! clb.withMethod("test", MTD_void, hasStatic ? ACC_STATIC : 0, mb -> mb.withFlags(v)));
return ClassFile.of().parse(bytes).methods().getFirst().flags();
};
! case FIELD -> v -> {
! var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb ->
! clb.withField("test", CD_int, fb -> fb.withFlags(v)));
return ClassFile.of().parse(bytes).fields().getFirst().flags();
};
! default -> null;
};
! var allFlags = EnumSet.allOf(AccessFlag.class);
! allFlags.removeIf(f -> !f.locations().contains(ctx));
! var r = new Random(123);
! for (int i = 0; i < 1000; i++) {
! var randomFlags = allFlags.stream().filter(f -> r.nextBoolean()).toArray(AccessFlag[]::new);
! assertEquals(intFactory.apply(flagsFactory.apply(randomFlags).flagsMask()).flags(), Set.of(randomFlags));
! var randomMask = r.nextInt(Short.MAX_VALUE);
! assertEquals(intFactory.apply(randomMask).flagsMask(), randomMask);
}
}
@Test
void testInvalidFlagsUse() {
*/
/*
* @test
* @summary Testing ClassFile AccessFlags.
+ * @modules java.base/jdk.internal.reflect
* @run junit AccessFlagsTest
*/
import java.lang.classfile.ClassFile;
import java.lang.constant.ClassDesc;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
import java.lang.reflect.AccessFlag;
import java.lang.classfile.AccessFlags;
import static java.lang.classfile.ClassFile.ACC_STATIC;
import static java.lang.constant.ConstantDescs.CD_int;
import static java.lang.constant.ConstantDescs.MTD_void;
import static org.junit.jupiter.api.Assertions.*;
+
+ import jdk.internal.reflect.PreviewAccessFlags;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.ParameterizedTest;
class AccessFlagsTest {
@ParameterizedTest
@EnumSource(names = { "CLASS", "METHOD", "FIELD" })
void testRandomAccessFlagsConverions(AccessFlag.Location ctx) {
! interface IntFlagsFactory {
! AccessFlags create(int flags, boolean preview);
! }
+ interface SymbolicFlagsFactory {
+ AccessFlags create(AccessFlag[] flags, boolean preview);
+ }
+ IntFlagsFactory intFactory = switch (ctx) {
+ case CLASS -> (v, preview) -> {
+ var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb -> {
+ if (preview) {
+ clb.withVersion(ClassFile.latestMajorVersion(), ClassFile.PREVIEW_MINOR_VERSION);
+ }
+ clb.withFlags(v);
+ });
return ClassFile.of().parse(bytes).flags();
};
! case METHOD -> (v, preview) -> {
! var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb -> {
! if (preview) {
+ clb.withVersion(ClassFile.latestMajorVersion(), ClassFile.PREVIEW_MINOR_VERSION);
+ }
+ clb.withMethod("test", MTD_void, v & ACC_STATIC, mb -> mb.withFlags(v));
+ });
return ClassFile.of().parse(bytes).methods().getFirst().flags();
};
! case FIELD -> (v, preview) -> {
! var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb -> {
! if (preview) {
+ clb.withVersion(ClassFile.latestMajorVersion(), ClassFile.PREVIEW_MINOR_VERSION);
+ }
+ clb.withField("test", CD_int, fb -> fb.withFlags(v));
+ });
return ClassFile.of().parse(bytes).fields().getFirst().flags();
};
! default -> fail();
};
! SymbolicFlagsFactory flagsFactory = switch (ctx) {
! case CLASS -> (v, preview) -> {
! var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb -> {
+ if (preview) {
+ clb.withVersion(ClassFile.latestMajorVersion(), ClassFile.PREVIEW_MINOR_VERSION);
+ }
+ clb.withFlags(v);
+ });
return ClassFile.of().parse(bytes).flags();
};
! case METHOD -> (v, preview) -> {
boolean hasStatic = Arrays.stream(v).anyMatch(f -> f == AccessFlag.STATIC);
! var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb -> {
! if (preview) {
+ clb.withVersion(ClassFile.latestMajorVersion(), ClassFile.PREVIEW_MINOR_VERSION);
+ }
+ clb.withMethod("test", MTD_void, hasStatic ? ACC_STATIC : 0, mb -> mb.withFlags(v));
+ });
return ClassFile.of().parse(bytes).methods().getFirst().flags();
};
! case FIELD -> (v, preview) -> {
! var bytes = ClassFile.of().build(ClassDesc.of("Test"), clb -> {
! if (preview) {
+ clb.withVersion(ClassFile.latestMajorVersion(), ClassFile.PREVIEW_MINOR_VERSION);
+ }
+ clb.withField("test", CD_int, fb -> fb.withFlags(v));
+ });
return ClassFile.of().parse(bytes).fields().getFirst().flags();
};
! default -> fail();
};
! for (boolean preview : new boolean[] {false, true}) {
! var allFlags = EnumSet.allOf(AccessFlag.class);
+ allFlags.removeIf(preview ? f -> !PreviewAccessFlags.locations(f).contains(ctx) : f -> !f.locations().contains(ctx));
! var r = new Random(123);
! for (int i = 0; i < 1000; i++) {
! var randomFlags = allFlags.stream().filter(f -> r.nextBoolean()).toArray(AccessFlag[]::new);
! assertEquals(intFactory.create(flagsFactory.create(randomFlags, preview).flagsMask(), preview).flags(), Set.of(randomFlags));
! var randomMask = r.nextInt(Short.MAX_VALUE);
! assertEquals(intFactory.create(randomMask, preview).flagsMask(), randomMask);
+ }
}
}
@Test
void testInvalidFlagsUse() {
< prev index next >