Skip to content

Commit 0eab5db

Browse files
committed
Address review 1/n
1 parent 875eb34 commit 0eab5db

File tree

15 files changed

+174
-93
lines changed

15 files changed

+174
-93
lines changed

src/java.base/share/classes/java/lang/Class.java

+30-60
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
package java.lang;
2727

2828
import java.lang.annotation.Annotation;
29-
import java.lang.classfile.Attribute;
29+
import java.lang.classfile.Attributes;
3030
import java.lang.classfile.ClassFile;
3131
import java.lang.classfile.ClassModel;
3232
import java.lang.classfile.MethodModel;
@@ -105,7 +105,7 @@
105105
import sun.reflect.generics.factory.GenericsFactory;
106106
import sun.reflect.generics.repository.ClassRepository;
107107
import sun.reflect.generics.repository.MethodRepository;
108-
import sun.reflect.generics.repository.ConstructorRepository;
108+
import sun.reflect.generics.repository.ExecutableRepository;
109109
import sun.reflect.generics.scope.ClassScope;
110110
import sun.security.util.SecurityConstants;
111111
import sun.reflect.annotation.*;
@@ -1737,7 +1737,7 @@ public Constructor<?> getEnclosingConstructor() throws SecurityException {
17371737
if (!enclosingInfo.isConstructor())
17381738
return null;
17391739

1740-
ConstructorRepository typeInfo = ConstructorRepository.make(enclosingInfo.getDescriptor(),
1740+
ExecutableRepository typeInfo = ExecutableRepository.make(enclosingInfo.getDescriptor(),
17411741
getFactory());
17421742
Type [] parameterTypes = typeInfo.getParameterTypes();
17431743
Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
@@ -2305,8 +2305,8 @@ public Constructor<?>[] getConstructors() throws SecurityException {
23052305
}
23062306

23072307
private Method[] filterOutDeconstructorsFromMethods(Method[] in) {
2308-
if (this.getClassLoader() != null ) {
2309-
Map<String, Boolean> isNotPattern = new HashMap<>();
2308+
if (this.getClassLoader() != null) {
2309+
Set<String> isPattern = new HashSet<>();
23102310
ClassModel cm = null;
23112311
try (InputStream resource = this.getClassLoader().getResourceAsStream(getName() + ".class")) {
23122312
if (resource == null) {
@@ -2318,13 +2318,10 @@ private Method[] filterOutDeconstructorsFromMethods(Method[] in) {
23182318
throw new RuntimeException(e);
23192319
}
23202320
for (MethodModel mm : cm.methods()) {
2321-
PatternAttribute pa = null;
2322-
for (Attribute<?> attribute : mm.attributes()) {
2323-
if (attribute instanceof PatternAttribute pap) pa = pap;
2324-
}
2325-
isNotPattern.put(mm.methodName().stringValue(), pa == null);
2321+
PatternAttribute pa = mm.findAttribute(Attributes.pattern()).orElse(null);
2322+
if (pa != null) isPattern.add(mm.methodName().stringValue());
23262323
}
2327-
Method[] ret = Arrays.stream(in).filter(m -> isNotPattern.getOrDefault(m.getName(), true)).toArray(Method[]::new);
2324+
Method[] ret = Arrays.stream(in).filter(m -> !isPattern.contains(m.getName())).toArray(Method[]::new);
23282325
return ret;
23292326
} else {
23302327
return in;
@@ -2353,12 +2350,12 @@ private Method[] filterOutDeconstructorsFromMethods(Method[] in) {
23532350

23542351
/**
23552352
* Returns a {@code Deconstructor} object that reflects the specified
2356-
* public constructor of the class represented by this {@code Class}
2353+
* public deconstructor of the class represented by this {@code Class}
23572354
* object.
23582355
*
23592356
* @param bindingTypes the array of the types of the bindings.
2360-
* @return the {@code Constructor} object of the public constructor that
2361-
* matches the specified {@code parameterTypes}
2357+
* @return the {@code Deconstructor} object of the public deconstructor that
2358+
* matches the specified {@code bindingTypes}
23622359
* @throws NoSuchPatternException if a matching deconstructor is not found.
23632360
*
23642361
* @throws SecurityException
@@ -2423,19 +2420,13 @@ private Deconstructor<?>[] getDeclaredDeconstructors0(Class<?>[] params, int whi
24232420
byte[] bytes = is.readAllBytes();
24242421
ClassModel cm = ClassFile.of().parse(bytes);
24252422
for (MethodModel mm : cm.methods()) {
2426-
PatternAttribute pa = null;
2427-
for (Attribute<?> attribute : mm.attributes()) {
2428-
if (attribute instanceof PatternAttribute pa_) pa = pa_;
2429-
}
2423+
PatternAttribute pa = mm.findAttribute(Attributes.pattern()).orElse(null);
24302424
if (pa != null) {
24312425
String descriptorFilter = null;
24322426

24332427
// generic signature detection
2434-
SignatureAttribute sa = null;
2435-
for (Attribute<?> attribute : pa.attributes()) {
2436-
if (attribute instanceof SignatureAttribute sa_) sa = sa_;
2437-
}
2438-
List<String> signatures = List.of();
2428+
SignatureAttribute sa = pa.findAttribute(Attributes.signature()).orElse(null);
2429+
List<String> signatures = null;
24392430
if (sa != null) {
24402431
signatures = sa.asMethodSignature().arguments().stream().map(a -> a.signatureString()).toList();
24412432
} else {
@@ -2451,17 +2442,8 @@ private Deconstructor<?>[] getDeclaredDeconstructors0(Class<?>[] params, int whi
24512442
if ((params.length == 0 || (params.length != 0 && pa.patternTypeSymbol().descriptorString().equals(descriptorFilter))) &&
24522443
(which == Member.DECLARED || mm.flags().has(AccessFlag.PUBLIC))) {
24532444
// binding annotations
2454-
RuntimeVisibleAnnotationsAttribute rva = null;
2455-
for (Attribute<?> attribute : mm.attributes()) {
2456-
if (attribute instanceof RuntimeVisibleAnnotationsAttribute rva_) rva = rva_;
2457-
}
2458-
ByteBuffer assembled_rva = null;
2459-
if (rva != null) {
2460-
byte rvaBytes[] = ((BoundAttribute) rva).contents(); // returns the full attribute
2461-
int rva_length = ((BoundAttribute) rva).payloadLen(); // already comes after the subtraction with 4
2462-
assembled_rva = ByteBuffer.wrap(rvaBytes, 0, rva_length);
2463-
// TODO: RuntimeInVisibleAnnotationsAttribute
2464-
}
2445+
RuntimeVisibleAnnotationsAttribute rva = mm.findAttribute(Attributes.runtimeVisibleAnnotations()).orElse(null);
2446+
ByteBuffer assembled_rva = getAnnotationContents(rva != null, (BoundAttribute) rva);
24652447

24662448
ArrayList<PatternBinding> deconstructorBindings = new ArrayList<>();
24672449
Deconstructor<?> currentDeconstructor = new Deconstructor<T>(this,
@@ -2475,37 +2457,16 @@ private Deconstructor<?>[] getDeclaredDeconstructors0(Class<?>[] params, int whi
24752457

24762458
// parameter names
24772459
var parameterList = pa.patternTypeSymbol().parameterList();
2478-
MethodParametersAttribute mp = null;
2479-
for (Attribute<?> attribute : pa.attributes()) {
2480-
if (attribute instanceof MethodParametersAttribute mp_) mp = mp_;
2481-
}
2460+
MethodParametersAttribute mp = pa.findAttribute(Attributes.methodParameters()).orElse(null);
24822461
List<String> parameterNameList = mp.parameters().stream().map(p -> p.name().get().stringValue()).toList();
24832462

24842463
// binding annotations
2485-
RuntimeVisibleParameterAnnotationsAttribute rvpa = null;
2486-
for (Attribute<?> attribute : pa.attributes()) {
2487-
if (attribute instanceof RuntimeVisibleParameterAnnotationsAttribute rvpa_) rvpa = rvpa_;
2488-
}
2489-
ByteBuffer assembled_rvpa = null;
2490-
if (rvpa != null) {
2491-
byte rvpaBytes[] = ((BoundAttribute) rvpa).contents();
2492-
int rvpa_length = ((BoundAttribute) rvpa).payloadLen();
2493-
assembled_rvpa = ByteBuffer.wrap(rvpaBytes, 0, rvpa_length);
2494-
// TODO: RuntimeInVisibleParameterAnnotationsAttribute
2495-
}
2464+
RuntimeVisibleParameterAnnotationsAttribute rvpa = pa.findAttribute(Attributes.runtimeVisibleParameterAnnotations()).orElse(null);
2465+
ByteBuffer assembled_rvpa = getAnnotationContents(rvpa != null, (BoundAttribute) rvpa);
24962466

24972467
// binding type annotations
2498-
RuntimeVisibleTypeAnnotationsAttribute rvta = null;
2499-
for (Attribute<?> attribute : pa.attributes()) {
2500-
if (attribute instanceof RuntimeVisibleTypeAnnotationsAttribute rvta_) rvta = rvta_;
2501-
}
2502-
ByteBuffer assembled_rvta = null;
2503-
if (rvpa != null) {
2504-
byte rvtaBytes[] = ((BoundAttribute) rvpa).contents();
2505-
int rvta_length = ((BoundAttribute) rvpa).payloadLen();
2506-
assembled_rvta = ByteBuffer.wrap(rvtaBytes, 0, rvta_length);
2507-
// TODO: RuntimeInVisibleTypeAnnotationsAttribute
2508-
}
2468+
RuntimeVisibleTypeAnnotationsAttribute rvta = pa.findAttribute(Attributes.runtimeVisibleTypeAnnotations()).orElse(null);
2469+
ByteBuffer assembled_rvta = getAnnotationContents(rvta != null, (BoundAttribute) rvta);
25092470

25102471
for (int i = 0; i < parameterList.size(); i++) {
25112472
Class<?> bindingClass = parameterList.get(i).resolveConstantDesc(MethodHandles.lookup());
@@ -2531,6 +2492,15 @@ private Deconstructor<?>[] getDeclaredDeconstructors0(Class<?>[] params, int whi
25312492
return decs.toArray(new Deconstructor<?>[decs.size()]);
25322493
}
25332494

2495+
private static ByteBuffer getAnnotationContents(boolean exists, BoundAttribute<?> boundAttribute) {
2496+
if (exists) {
2497+
byte rvpaBytes[] = boundAttribute.contents();
2498+
int rvpa_length = boundAttribute.payloadLen();
2499+
return ByteBuffer.wrap(rvpaBytes, 0, rvpa_length);
2500+
}
2501+
return null;
2502+
}
2503+
25342504
/**
25352505
* Returns a {@code Deconstructor} object that reflects the specified
25362506
* deconstructor of the class represented by this

src/java.base/share/classes/java/lang/NoSuchPatternException.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2024, 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
@@ -28,7 +28,7 @@
2828
/**
2929
* Thrown when a particular pattern cannot be found.
3030
*
31-
* @since 1.0
31+
* @since 24
3232
*/
3333
public class NoSuchPatternException extends ReflectiveOperationException {
3434
@java.io.Serial

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ public Set<Location> apply(ClassFileFormatVersion cffv) {
381381
new Function<ClassFileFormatVersion, Set<Location>>() {
382382
@Override
383383
public Set<Location> apply(ClassFileFormatVersion cffv) {
384-
return (cffv.compareTo(ClassFileFormatVersion.RELEASE_22) >= 0 ) ?
384+
return (cffv.compareTo(ClassFileFormatVersion.RELEASE_24) >= 0 ) ?
385385
Location.SET_PATTERN :
386386
Location.EMPTY_SET;}
387387
}),
@@ -394,7 +394,7 @@ public Set<Location> apply(ClassFileFormatVersion cffv) {
394394
new Function<ClassFileFormatVersion, Set<Location>>() {
395395
@Override
396396
public Set<Location> apply(ClassFileFormatVersion cffv) {
397-
return (cffv.compareTo(ClassFileFormatVersion.RELEASE_22) >= 0 ) ?
397+
return (cffv.compareTo(ClassFileFormatVersion.RELEASE_24) >= 0 ) ?
398398
Location.SET_PATTERN :
399399
Location.EMPTY_SET;}
400400
}),

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import jdk.internal.vm.annotation.Stable;
3535
import sun.reflect.annotation.TypeAnnotation;
3636
import sun.reflect.annotation.TypeAnnotationParser;
37-
import sun.reflect.generics.repository.ConstructorRepository;
37+
import sun.reflect.generics.repository.ExecutableRepository;
3838
import sun.reflect.generics.repository.GenericDeclRepository;
3939
import sun.reflect.generics.factory.CoreReflectionFactory;
4040
import sun.reflect.generics.factory.GenericsFactory;
@@ -73,7 +73,7 @@ public final class Constructor<T> extends Executable {
7373
// Generics and annotations support
7474
private final transient String signature;
7575
// generic info repository; lazily initialized
76-
private transient volatile ConstructorRepository genericInfo;
76+
private transient volatile ExecutableRepository genericInfo;
7777
private final byte[] annotations;
7878
private final byte[] parameterAnnotations;
7979

@@ -86,13 +86,13 @@ private GenericsFactory getFactory() {
8686

8787
// Accessor for generic info repository
8888
@Override
89-
ConstructorRepository getGenericInfo() {
89+
ExecutableRepository getGenericInfo() {
9090
var genericInfo = this.genericInfo;
9191
// lazily initialize repository if necessary
9292
if (genericInfo == null) {
9393
// create and cache generic info repository
9494
genericInfo =
95-
ConstructorRepository.make(getSignature(),
95+
ExecutableRepository.make(getSignature(),
9696
getFactory());
9797
this.genericInfo = genericInfo;
9898
}

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

+23-8
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@
2727

2828
import jdk.internal.reflect.CallerSensitive;
2929
import jdk.internal.reflect.Reflection;
30-
import jdk.internal.vm.annotation.Stable;
3130
import sun.reflect.generics.factory.CoreReflectionFactory;
3231
import sun.reflect.generics.factory.GenericsFactory;
33-
import sun.reflect.generics.repository.ConstructorRepository;
32+
import sun.reflect.generics.repository.ExecutableRepository;
3433
import sun.reflect.generics.repository.GenericDeclRepository;
3534
import sun.reflect.generics.scope.DeconstructorScope;
35+
import sun.reflect.generics.tree.MethodTypeSignature;
3636

3737
import java.lang.annotation.Annotation;
3838
import java.lang.invoke.MethodType;
@@ -60,14 +60,15 @@
6060
public final class Deconstructor<T> extends Executable {
6161
private final Class<T> clazz;
6262
private final int slot;
63+
private ArrayList<PatternBinding> patternBindings;
64+
6365
private final int modifiers;
6466
private final int patternFlags;
6567
// Generics and annotations support
6668
private final transient String signature;
6769
// generic info repository; lazily initialized
68-
private transient volatile ConstructorRepository genericInfo;
70+
private transient volatile ExecutableRepository genericInfo;
6971
private final byte[] annotations;
70-
private ArrayList<PatternBinding> patternBindings;
7172

7273
// Generics infrastructure
7374
// Accessor for factory
@@ -121,7 +122,7 @@ public Deconstructor(Class<T> declaringClass,
121122
*/
122123
Deconstructor<T> copy() {
123124
// This routine enables sharing of ConstructorAccessor objects
124-
// among Constructor objects which refer to the same underlying
125+
// among Deconstructor objects which refer to the same underlying
125126
// method in the VM. (All of this contortion is only necessary
126127
// because of the "accessibility" bit in AccessibleObject,
127128
// which implicitly requires that new java.lang.reflect
@@ -145,7 +146,7 @@ Deconstructor<T> copy() {
145146
* {@inheritDoc}
146147
*
147148
* <p> A {@code SecurityException} is also thrown if this object is a
148-
* {@code Constructor} object for the class {@code Class} and {@code flag}
149+
* {@code Deconstructor} object for the class {@code Class} and {@code flag}
149150
* is true. </p>
150151
*
151152
* @param flag {@inheritDoc}
@@ -216,6 +217,20 @@ public Annotation[][] getParameterAnnotations() {
216217
return new Annotation[0][];
217218
}
218219

220+
/**
221+
* Returns an array of arrays of {@code Annotation}s that
222+
* represent the annotations on the bindings, in
223+
* declaration order, of the {@code Deconstructor} represented by
224+
* this object.
225+
*
226+
* @return an array of arrays that represent the annotations on
227+
* the bindings, in declaration order, of
228+
* the deconstructor represented by this object
229+
*/
230+
public Annotation[][] getBindingAnnotations() {
231+
return patternBindings.stream().map(pb -> pb.getAnnotations()).toArray(Annotation[][]::new);
232+
}
233+
219234
@Override
220235
boolean handleParameterNumberMismatch(int resultLength, Class<?>[] parameterTypes) {
221236
return false;
@@ -315,13 +330,13 @@ boolean hasGenericInformation() {
315330
return false;
316331
}
317332

318-
ConstructorRepository getGenericInfo() {
333+
ExecutableRepository getGenericInfo() {
319334
var genericInfo = this.genericInfo;
320335
// lazily initialize repository if necessary
321336
if (genericInfo == null) {
322337
// create and cache generic info repository
323338
genericInfo =
324-
ConstructorRepository.make(getSignature(),
339+
ExecutableRepository.make(getSignature(),
325340
getFactory());
326341
this.genericInfo = genericInfo;
327342
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
import sun.reflect.annotation.TypeAnnotationParser;
4141
import sun.reflect.annotation.TypeAnnotation;
4242
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
43-
import sun.reflect.generics.repository.ConstructorRepository;
43+
import sun.reflect.generics.repository.ExecutableRepository;
4444

4545
/**
4646
* A shared superclass for the common functionality of {@link Method}
@@ -67,7 +67,7 @@ public abstract sealed class Executable extends AccessibleObject
6767
*/
6868
abstract boolean hasGenericInformation();
6969

70-
abstract ConstructorRepository getGenericInfo();
70+
abstract ExecutableRepository getGenericInfo();
7171

7272
boolean equalParamTypes(Class<?>[] params1, Class<?>[] params2) {
7373
/* Avoid unnecessary cloning */

0 commit comments

Comments
 (0)