Skip to content

Commit a39c15a

Browse files
committed
8347471: Provide valid flags and mask in AccessFlag.Location
1 parent 379d05b commit a39c15a

File tree

7 files changed

+413
-264
lines changed

7 files changed

+413
-264
lines changed

src/java.base/share/classes/java/lang/reflect/AccessFlag.java

+258-200
Large diffs are not rendered by default.

test/jdk/java/lang/reflect/AccessFlag/BasicAccessFlagTest.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -158,5 +158,20 @@ private static void testLocationsNullHandling() {
158158
; // Expected
159159
}
160160
}
161+
162+
for (var location : AccessFlag.Location.values()) {
163+
try {
164+
location.flags(null);
165+
throw new RuntimeException("Did not get NPE on " + location + ".definedFlags(null)");
166+
} catch (NullPointerException npe ) {
167+
; // Expected
168+
}
169+
try {
170+
location.flags(null);
171+
throw new RuntimeException("Did not get NPE on " + location + ".definedFlags(null)");
172+
} catch (NullPointerException npe ) {
173+
; // Expected
174+
}
175+
}
161176
}
162177
}

test/jdk/java/lang/reflect/AccessFlag/ClassAccessFlagTest.java

+28-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,8 @@
3131
import java.lang.reflect.*;
3232
import java.util.*;
3333

34+
import static java.lang.reflect.AccessFlag.*;
35+
3436
/*
3537
* Class access flags that can directly or indirectly declared in
3638
* source include:
@@ -47,7 +49,7 @@
4749
* file. Therefore, this test does not attempt to probe the setting of
4850
* that access flag.
4951
*/
50-
@ExpectedClassFlags("[PUBLIC, FINAL, SUPER]")
52+
@ExpectedClassFlags({PUBLIC, FINAL, SUPER})
5153
public final class ClassAccessFlagTest {
5254
public static void main(String... args) {
5355
// Top-level and auxiliary classes; i.e. non-inner classes
@@ -76,10 +78,12 @@ private static void checkClass(Class<?> clazz) {
7678
ExpectedClassFlags expected =
7779
clazz.getAnnotation(ExpectedClassFlags.class);
7880
if (expected != null) {
79-
String actual = clazz.accessFlags().toString();
80-
if (!expected.value().equals(actual)) {
81+
Set<AccessFlag> base = EnumSet.noneOf(AccessFlag.class);
82+
Collections.addAll(base, expected.value());
83+
Set<AccessFlag> actual = clazz.accessFlags();
84+
if (!base.equals(actual)) {
8185
throw new RuntimeException("On " + clazz +
82-
" expected " + expected.value() +
86+
" expected " + base +
8387
" got " + actual);
8488
}
8589
}
@@ -98,7 +102,7 @@ private static void checkPrimitives() {
98102
void.class // same access flag rules
99103
};
100104

101-
var expected = Set.of(AccessFlag.PUBLIC,
105+
var expected = Set.of(PUBLIC,
102106
AccessFlag.FINAL,
103107
AccessFlag.ABSTRACT);
104108

@@ -127,8 +131,8 @@ private static void checkArrays() {
127131
for (var accessClass : accessClasses) {
128132
AccessFlag accessLevel;
129133
var flags = accessClass.accessFlags();
130-
if (flags.contains(AccessFlag.PUBLIC))
131-
accessLevel = AccessFlag.PUBLIC;
134+
if (flags.contains(PUBLIC))
135+
accessLevel = PUBLIC;
132136
else if (flags.contains(AccessFlag.PROTECTED))
133137
accessLevel = AccessFlag.PROTECTED;
134138
else if (flags.contains(AccessFlag.PRIVATE))
@@ -145,7 +149,7 @@ else if (flags.contains(AccessFlag.PRIVATE))
145149
}
146150
} else {
147151
if (containsAny(arrayClass.accessFlags(),
148-
Set.of(AccessFlag.PUBLIC,
152+
Set.of(PUBLIC,
149153
AccessFlag.PROTECTED,
150154
AccessFlag.PRIVATE))) {
151155
throw new RuntimeException("Unexpected access flags on " +
@@ -161,32 +165,32 @@ else if (flags.contains(AccessFlag.PRIVATE))
161165
// PUBLIC, PRIVATE, PROTECTED, STATIC, FINAL, INTERFACE, ABSTRACT,
162166
// SYNTHETIC, ANNOTATION, ENUM.
163167

164-
@ExpectedClassFlags("[PUBLIC, STATIC, INTERFACE, ABSTRACT]")
168+
@ExpectedClassFlags({PUBLIC, STATIC, INTERFACE, ABSTRACT})
165169
public interface PublicInterface {}
166-
@ExpectedClassFlags("[PROTECTED, STATIC, INTERFACE, ABSTRACT]")
170+
@ExpectedClassFlags({PROTECTED, STATIC, INTERFACE, ABSTRACT})
167171
protected interface ProtectedInterface {}
168-
@ExpectedClassFlags("[PRIVATE, STATIC, INTERFACE, ABSTRACT]")
172+
@ExpectedClassFlags({PRIVATE, STATIC, INTERFACE, ABSTRACT})
169173
private interface PrivateInterface {}
170-
@ExpectedClassFlags("[STATIC, INTERFACE, ABSTRACT]")
174+
@ExpectedClassFlags({STATIC, INTERFACE, ABSTRACT})
171175
/*package*/ interface PackageInterface {}
172176

173-
@ExpectedClassFlags("[FINAL]")
177+
@ExpectedClassFlags({FINAL})
174178
/*package*/ final class TestFinalClass {}
175179

176-
@ExpectedClassFlags("[ABSTRACT]")
180+
@ExpectedClassFlags({ABSTRACT})
177181
/*package*/ abstract class TestAbstractClass {}
178182

179-
@ExpectedClassFlags("[STATIC, INTERFACE, ABSTRACT, ANNOTATION]")
183+
@ExpectedClassFlags({STATIC, INTERFACE, ABSTRACT, ANNOTATION})
180184
/*package*/ @interface TestMarkerAnnotation {}
181185

182-
@ExpectedClassFlags("[PUBLIC, STATIC, FINAL, ENUM]")
186+
@ExpectedClassFlags({PUBLIC, STATIC, FINAL, ENUM})
183187
public enum MetaSynVar {
184188
QUUX;
185189
}
186190

187191
// Is there is at least one special enum constant, the enum class
188192
// itself is implicitly abstract rather than final.
189-
@ExpectedClassFlags("[PROTECTED, STATIC, ABSTRACT, ENUM]")
193+
@ExpectedClassFlags({PROTECTED, STATIC, ABSTRACT, ENUM})
190194
protected enum MetaSynVar2 {
191195
WOMBAT{
192196
@Override
@@ -195,24 +199,24 @@ protected enum MetaSynVar2 {
195199
public abstract int foo();
196200
}
197201

198-
@ExpectedClassFlags("[PRIVATE, ABSTRACT]")
202+
@ExpectedClassFlags({PRIVATE, ABSTRACT})
199203
private abstract class Foo {}
200204

201-
@ExpectedClassFlags("[STATIC, INTERFACE, ABSTRACT]")
205+
@ExpectedClassFlags({STATIC, INTERFACE, ABSTRACT})
202206
interface StaticTestInterface {}
203207
}
204208

205209
@Retention(RetentionPolicy.RUNTIME)
206-
@ExpectedClassFlags("[INTERFACE, ABSTRACT, ANNOTATION]")
210+
@ExpectedClassFlags({INTERFACE, ABSTRACT, ANNOTATION})
207211
@interface ExpectedClassFlags {
208-
String value();
212+
AccessFlag[] value();
209213
}
210214

211-
@ExpectedClassFlags("[INTERFACE, ABSTRACT]")
215+
@ExpectedClassFlags({INTERFACE, ABSTRACT})
212216
interface TestInterface {}
213217

214218

215-
@ExpectedClassFlags("[FINAL, SUPER, ENUM]")
219+
@ExpectedClassFlags({FINAL, SUPER, ENUM})
216220
enum TestOuterEnum {
217221
INSTANCE;
218222
}

test/jdk/java/lang/reflect/AccessFlag/FieldAccessFlagTest.java

+19-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,11 @@
2929

3030
import java.lang.annotation.*;
3131
import java.lang.reflect.*;
32+
import java.util.Collections;
33+
import java.util.EnumSet;
34+
import java.util.Set;
35+
36+
import static java.lang.reflect.AccessFlag.*;
3237

3338
/*
3439
* Field modifiers include:
@@ -54,39 +59,41 @@ private static void checkField(Field field) {
5459
ExpectedFieldFlags expected =
5560
field.getAnnotation(ExpectedFieldFlags.class);
5661
if (expected != null) {
57-
String actual = field.accessFlags().toString();
58-
if (!expected.value().equals(actual)) {
62+
Set<AccessFlag> base = EnumSet.noneOf(AccessFlag.class);
63+
Collections.addAll(base, expected.value());
64+
Set<AccessFlag> actual = field.accessFlags();
65+
if (!base.equals(actual)) {
5966
throw new RuntimeException("On " + field +
60-
" expected " + expected.value() +
61-
" got " + actual);
67+
" expected " + base +
68+
" got " + actual);
6269
}
6370
}
6471
}
6572

6673
// Fields
67-
@ExpectedFieldFlags("[PUBLIC, STATIC, FINAL]")
74+
@ExpectedFieldFlags({PUBLIC, STATIC, FINAL})
6875
public static final String f1 = "foo";
6976

70-
@ExpectedFieldFlags("[PRIVATE, VOLATILE, TRANSIENT]")
77+
@ExpectedFieldFlags({PRIVATE, VOLATILE, TRANSIENT})
7178
private volatile transient String secret = "xxyzzy";
7279

73-
@ExpectedFieldFlags("[PROTECTED]")
80+
@ExpectedFieldFlags({PROTECTED})
7481
protected String meadow = "";
7582

7683
// Enum constant should have the enum access flag set
7784
static enum MetaSynVar {
78-
@ExpectedFieldFlags("[PUBLIC, STATIC, FINAL, ENUM]")
85+
@ExpectedFieldFlags({PUBLIC, STATIC, FINAL, ENUM})
7986
FOO,
8087

81-
@ExpectedFieldFlags("[PUBLIC, STATIC, FINAL, ENUM]")
88+
@ExpectedFieldFlags({PUBLIC, STATIC, FINAL, ENUM})
8289
BAR;
8390

84-
@ExpectedFieldFlags("[PRIVATE]") // no "ENUM"
91+
@ExpectedFieldFlags({PRIVATE}) // no "ENUM"
8592
private int field = 0;
8693
}
8794

8895
@Retention(RetentionPolicy.RUNTIME)
8996
private @interface ExpectedFieldFlags {
90-
String value();
97+
AccessFlag[] value();
9198
}
9299
}

test/jdk/java/lang/reflect/AccessFlag/MethodAccessFlagTest.java

+26-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,11 @@
3434

3535
import java.lang.annotation.*;
3636
import java.lang.reflect.*;
37+
import java.util.Collections;
38+
import java.util.EnumSet;
39+
import java.util.Set;
40+
41+
import static java.lang.reflect.AccessFlag.*;
3742

3843
/*
3944
* Method modifiers include:
@@ -49,7 +54,7 @@
4954
* Method parameters can be final, synthetic, and mandated.
5055
*/
5156
public abstract class MethodAccessFlagTest {
52-
@ExpectedMethodFlags("[PUBLIC, STATIC, VARARGS]")
57+
@ExpectedMethodFlags({PUBLIC, STATIC, VARARGS})
5358
public static void main(String... args) {
5459
for (var ctor :
5560
MethodAccessFlagTest.class.getDeclaredConstructors()) {
@@ -136,11 +141,17 @@ enum TestEnum {
136141
}
137142

138143
private static void checkExecutable(Executable method) {
139-
ExpectedMethodFlags emf =
144+
ExpectedMethodFlags expected =
140145
method.getAnnotation(ExpectedMethodFlags.class);
141-
if (emf != null) {
142-
String actual = method.accessFlags().toString();
143-
checkString(method.toString(), emf.value(), actual);
146+
if (expected != null) {
147+
Set<AccessFlag> base = EnumSet.noneOf(AccessFlag.class);
148+
Collections.addAll(base, expected.value());
149+
Set<AccessFlag> actual = method.accessFlags();
150+
if (!base.equals(actual)) {
151+
throw new RuntimeException("On " + method +
152+
" expected " + base +
153+
" got " + actual);
154+
}
144155
}
145156
}
146157

@@ -155,33 +166,33 @@ private static void checkString(String declaration,
155166
}
156167

157168
// Constructors
158-
@ExpectedMethodFlags("[PUBLIC]")
169+
@ExpectedMethodFlags({PUBLIC})
159170
public MethodAccessFlagTest() {}
160171

161-
@ExpectedMethodFlags("[PROTECTED]")
172+
@ExpectedMethodFlags({PROTECTED})
162173
protected MethodAccessFlagTest(int i) {super();}
163174

164-
@ExpectedMethodFlags("[PRIVATE]")
175+
@ExpectedMethodFlags({PRIVATE})
165176
private MethodAccessFlagTest(String s) {super();}
166177

167178
// Methods
168-
@ExpectedMethodFlags("[PROTECTED, SYNCHRONIZED]")
179+
@ExpectedMethodFlags({PROTECTED, SYNCHRONIZED})
169180
protected synchronized void m0() {}
170181

171-
@ExpectedMethodFlags("[PRIVATE]")
182+
@ExpectedMethodFlags({PRIVATE})
172183
private void m1() {}
173184

174-
@ExpectedMethodFlags("[ABSTRACT]")
185+
@ExpectedMethodFlags({ABSTRACT})
175186
abstract void m2();
176187

177-
@ExpectedMethodFlags("[PUBLIC, FINAL]")
188+
@ExpectedMethodFlags({PUBLIC, FINAL})
178189
public final void m3() {}
179190

180-
@ExpectedMethodFlags("[NATIVE]")
191+
@ExpectedMethodFlags({NATIVE})
181192
native void m4();
182193

183194
@Retention(RetentionPolicy.RUNTIME)
184195
private @interface ExpectedMethodFlags {
185-
String value();
196+
AccessFlag[] value();
186197
}
187198
}

test/jdk/java/lang/reflect/AccessFlag/StrictAccessFlagTest.java

+15-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -35,14 +35,19 @@
3535

3636
import java.lang.annotation.*;
3737
import java.lang.reflect.*;
38+
import java.util.Collections;
39+
import java.util.EnumSet;
40+
import java.util.Set;
41+
42+
import static java.lang.reflect.AccessFlag.*;
3843

3944
/*
4045
* Test expected value of ACC_STRICT access flag.
4146
*/
4247
// Declaring the class strictfp implicitly sets ACC_STRICT on all its
4348
// methods and constructors.
4449
public strictfp class StrictAccessFlagTest {
45-
@ExpectedFlags("[PUBLIC, STATIC, VARARGS, STRICT]")
50+
@ExpectedFlags({PUBLIC, STATIC, VARARGS, STRICT})
4651
public static void main(String... args) {
4752
for (var ctor :
4853
StrictAccessFlagTest.class.getDeclaredConstructors()) {
@@ -59,21 +64,23 @@ private static void checkExecutable(Executable method) {
5964
ExpectedFlags expected =
6065
method.getAnnotation(ExpectedFlags.class);
6166
if (expected != null) {
62-
String actual = method.accessFlags().toString();
63-
if (!expected.value().equals(actual)) {
67+
Set<AccessFlag> base = EnumSet.noneOf(AccessFlag.class);
68+
Collections.addAll(base, expected.value());
69+
Set<AccessFlag> actual = method.accessFlags();
70+
if (!base.equals(actual)) {
6471
throw new RuntimeException("On " + method +
65-
" expected " + expected.value() +
66-
" got " + actual);
72+
" expected " + base +
73+
" got " + actual);
6774
}
6875
}
6976
}
7077

7178
// Constructor
72-
@ExpectedFlags("[PUBLIC, STRICT]")
79+
@ExpectedFlags({PUBLIC, STRICT})
7380
public StrictAccessFlagTest() {}
7481

7582
@Retention(RetentionPolicy.RUNTIME)
7683
private @interface ExpectedFlags {
77-
String value();
84+
AccessFlag[] value();
7885
}
7986
}

0 commit comments

Comments
 (0)