Skip to content

Commit f5248ff

Browse files
committed
Upgrade to ASM 7.1
Closes gh-22503
1 parent a06ab6d commit f5248ff

16 files changed

+841
-541
lines changed

spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ public abstract class AnnotationVisitor {
4343
*/
4444
protected final int api;
4545

46-
/** The annotation visitor to which this visitor must delegate method calls. May be null. */
46+
/**
47+
* The annotation visitor to which this visitor must delegate method calls. May be {@literal
48+
* null}.
49+
*/
4750
protected AnnotationVisitor av;
4851

4952
/**
@@ -62,11 +65,11 @@ public AnnotationVisitor(final int api) {
6265
* @param api the ASM API version implemented by this visitor. Must be one of {@link
6366
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
6467
* @param annotationVisitor the annotation visitor to which this visitor must delegate method
65-
* calls. May be null.
68+
* calls. May be {@literal null}.
6669
*/
6770
public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) {
68-
if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) {
69-
throw new IllegalArgumentException();
71+
if (api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4) {
72+
throw new IllegalArgumentException("Unsupported api " + api);
7073
}
7174
this.api = api;
7275
this.av = annotationVisitor;

spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java

Lines changed: 149 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ final class AnnotationWriter extends AnnotationVisitor {
9191
private AnnotationWriter nextAnnotation;
9292

9393
// -----------------------------------------------------------------------------------------------
94-
// Constructors
94+
// Constructors and factories
9595
// -----------------------------------------------------------------------------------------------
9696

9797
/**
@@ -104,8 +104,8 @@ final class AnnotationWriter extends AnnotationVisitor {
104104
* the visited content must be stored. This ByteVector must already contain all the fields of
105105
* the structure except the last one (the element_value_pairs array).
106106
* @param previousAnnotation the previously visited annotation of the
107-
* Runtime[In]Visible[Type]Annotations attribute to which this annotation belongs, or null in
108-
* other cases (e.g. nested or array annotations).
107+
* Runtime[In]Visible[Type]Annotations attribute to which this annotation belongs, or
108+
* {@literal null} in other cases (e.g. nested or array annotations).
109109
*/
110110
AnnotationWriter(
111111
final SymbolTable symbolTable,
@@ -125,21 +125,61 @@ final class AnnotationWriter extends AnnotationVisitor {
125125
}
126126

127127
/**
128-
* Constructs a new {@link AnnotationWriter} using named values.
128+
* Creates a new {@link AnnotationWriter} using named values.
129129
*
130130
* @param symbolTable where the constants used in this AnnotationWriter must be stored.
131-
* @param annotation where the 'annotation' or 'type_annotation' JVMS structure corresponding to
132-
* the visited content must be stored. This ByteVector must already contain all the fields of
133-
* the structure except the last one (the element_value_pairs array).
131+
* @param descriptor the class descriptor of the annotation class.
134132
* @param previousAnnotation the previously visited annotation of the
135-
* Runtime[In]Visible[Type]Annotations attribute to which this annotation belongs, or null in
136-
* other cases (e.g. nested or array annotations).
133+
* Runtime[In]Visible[Type]Annotations attribute to which this annotation belongs, or
134+
* {@literal null} in other cases (e.g. nested or array annotations).
135+
* @return a new {@link AnnotationWriter} for the given annotation descriptor.
137136
*/
138-
AnnotationWriter(
137+
static AnnotationWriter create(
139138
final SymbolTable symbolTable,
140-
final ByteVector annotation,
139+
final String descriptor,
140+
final AnnotationWriter previousAnnotation) {
141+
// Create a ByteVector to hold an 'annotation' JVMS structure.
142+
// See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16.
143+
ByteVector annotation = new ByteVector();
144+
// Write type_index and reserve space for num_element_value_pairs.
145+
annotation.putShort(symbolTable.addConstantUtf8(descriptor)).putShort(0);
146+
return new AnnotationWriter(
147+
symbolTable, /* useNamedValues = */ true, annotation, previousAnnotation);
148+
}
149+
150+
/**
151+
* Creates a new {@link AnnotationWriter} using named values.
152+
*
153+
* @param symbolTable where the constants used in this AnnotationWriter must be stored.
154+
* @param typeRef a reference to the annotated type. The sort of this type reference must be
155+
* {@link TypeReference#CLASS_TYPE_PARAMETER}, {@link
156+
* TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See
157+
* {@link TypeReference}.
158+
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or
159+
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
160+
* 'typeRef' as a whole.
161+
* @param descriptor the class descriptor of the annotation class.
162+
* @param previousAnnotation the previously visited annotation of the
163+
* Runtime[In]Visible[Type]Annotations attribute to which this annotation belongs, or
164+
* {@literal null} in other cases (e.g. nested or array annotations).
165+
* @return a new {@link AnnotationWriter} for the given type annotation reference and descriptor.
166+
*/
167+
static AnnotationWriter create(
168+
final SymbolTable symbolTable,
169+
final int typeRef,
170+
final TypePath typePath,
171+
final String descriptor,
141172
final AnnotationWriter previousAnnotation) {
142-
this(symbolTable, /* useNamedValues = */ true, annotation, previousAnnotation);
173+
// Create a ByteVector to hold a 'type_annotation' JVMS structure.
174+
// See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20.
175+
ByteVector typeAnnotation = new ByteVector();
176+
// Write target_type, target_info, and target_path.
177+
TypeReference.putTarget(typeRef, typeAnnotation);
178+
TypePath.put(typePath, typeAnnotation);
179+
// Write type_index and reserve space for num_element_value_pairs.
180+
typeAnnotation.putShort(symbolTable.addConstantUtf8(descriptor)).putShort(0);
181+
return new AnnotationWriter(
182+
symbolTable, /* useNamedValues = */ true, typeAnnotation, previousAnnotation);
143183
}
144184

145185
// -----------------------------------------------------------------------------------------------
@@ -244,7 +284,7 @@ public AnnotationVisitor visitAnnotation(final String name, final String descrip
244284
}
245285
// Write tag and type_index, and reserve 2 bytes for num_element_value_pairs.
246286
annotation.put12('@', symbolTable.addConstantUtf8(descriptor)).putShort(0);
247-
return new AnnotationWriter(symbolTable, annotation, null);
287+
return new AnnotationWriter(symbolTable, /* useNamedValues = */ true, annotation, null);
248288
}
249289

250290
@Override
@@ -284,7 +324,7 @@ public void visitEnd() {
284324
* and all its <i>predecessors</i> (see {@link #previousAnnotation}. Also adds the attribute name
285325
* to the constant pool of the class (if not null).
286326
*
287-
* @param attributeName one of "Runtime[In]Visible[Type]Annotations", or null.
327+
* @param attributeName one of "Runtime[In]Visible[Type]Annotations", or {@literal null}.
288328
* @return the size in bytes of a Runtime[In]Visible[Type]Annotations attribute containing this
289329
* annotation and all its predecessors. This includes the size of the attribute_name_index and
290330
* attribute_length fields.
@@ -303,6 +343,56 @@ int computeAnnotationsSize(final String attributeName) {
303343
return attributeSize;
304344
}
305345

346+
/**
347+
* Returns the size of the Runtime[In]Visible[Type]Annotations attributes containing the given
348+
* annotations and all their <i>predecessors</i> (see {@link #previousAnnotation}. Also adds the
349+
* attribute names to the constant pool of the class (if not null).
350+
*
351+
* @param lastRuntimeVisibleAnnotation The last runtime visible annotation of a field, method or
352+
* class. The previous ones can be accessed with the {@link #previousAnnotation} field. May be
353+
* {@literal null}.
354+
* @param lastRuntimeInvisibleAnnotation The last runtime invisible annotation of this a field,
355+
* method or class. The previous ones can be accessed with the {@link #previousAnnotation}
356+
* field. May be {@literal null}.
357+
* @param lastRuntimeVisibleTypeAnnotation The last runtime visible type annotation of this a
358+
* field, method or class. The previous ones can be accessed with the {@link
359+
* #previousAnnotation} field. May be {@literal null}.
360+
* @param lastRuntimeInvisibleTypeAnnotation The last runtime invisible type annotation of a
361+
* field, method or class field. The previous ones can be accessed with the {@link
362+
* #previousAnnotation} field. May be {@literal null}.
363+
* @return the size in bytes of a Runtime[In]Visible[Type]Annotations attribute containing the
364+
* given annotations and all their predecessors. This includes the size of the
365+
* attribute_name_index and attribute_length fields.
366+
*/
367+
static int computeAnnotationsSize(
368+
final AnnotationWriter lastRuntimeVisibleAnnotation,
369+
final AnnotationWriter lastRuntimeInvisibleAnnotation,
370+
final AnnotationWriter lastRuntimeVisibleTypeAnnotation,
371+
final AnnotationWriter lastRuntimeInvisibleTypeAnnotation) {
372+
int size = 0;
373+
if (lastRuntimeVisibleAnnotation != null) {
374+
size +=
375+
lastRuntimeVisibleAnnotation.computeAnnotationsSize(
376+
Constants.RUNTIME_VISIBLE_ANNOTATIONS);
377+
}
378+
if (lastRuntimeInvisibleAnnotation != null) {
379+
size +=
380+
lastRuntimeInvisibleAnnotation.computeAnnotationsSize(
381+
Constants.RUNTIME_INVISIBLE_ANNOTATIONS);
382+
}
383+
if (lastRuntimeVisibleTypeAnnotation != null) {
384+
size +=
385+
lastRuntimeVisibleTypeAnnotation.computeAnnotationsSize(
386+
Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
387+
}
388+
if (lastRuntimeInvisibleTypeAnnotation != null) {
389+
size +=
390+
lastRuntimeInvisibleTypeAnnotation.computeAnnotationsSize(
391+
Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
392+
}
393+
return size;
394+
}
395+
306396
/**
307397
* Puts a Runtime[In]Visible[Type]Annotations attribute containing this annotations and all its
308398
* <i>predecessors</i> (see {@link #previousAnnotation} in the given ByteVector. Annotations are
@@ -335,6 +425,51 @@ void putAnnotations(final int attributeNameIndex, final ByteVector output) {
335425
}
336426
}
337427

428+
/**
429+
* Puts the Runtime[In]Visible[Type]Annotations attributes containing the given annotations and
430+
* all their <i>predecessors</i> (see {@link #previousAnnotation} in the given ByteVector.
431+
* Annotations are put in the same order they have been visited.
432+
*
433+
* @param symbolTable where the constants used in the AnnotationWriter instances are stored.
434+
* @param lastRuntimeVisibleAnnotation The last runtime visible annotation of a field, method or
435+
* class. The previous ones can be accessed with the {@link #previousAnnotation} field. May be
436+
* {@literal null}.
437+
* @param lastRuntimeInvisibleAnnotation The last runtime invisible annotation of this a field,
438+
* method or class. The previous ones can be accessed with the {@link #previousAnnotation}
439+
* field. May be {@literal null}.
440+
* @param lastRuntimeVisibleTypeAnnotation The last runtime visible type annotation of this a
441+
* field, method or class. The previous ones can be accessed with the {@link
442+
* #previousAnnotation} field. May be {@literal null}.
443+
* @param lastRuntimeInvisibleTypeAnnotation The last runtime invisible type annotation of a
444+
* field, method or class field. The previous ones can be accessed with the {@link
445+
* #previousAnnotation} field. May be {@literal null}.
446+
* @param output where the attributes must be put.
447+
*/
448+
static void putAnnotations(
449+
final SymbolTable symbolTable,
450+
final AnnotationWriter lastRuntimeVisibleAnnotation,
451+
final AnnotationWriter lastRuntimeInvisibleAnnotation,
452+
final AnnotationWriter lastRuntimeVisibleTypeAnnotation,
453+
final AnnotationWriter lastRuntimeInvisibleTypeAnnotation,
454+
final ByteVector output) {
455+
if (lastRuntimeVisibleAnnotation != null) {
456+
lastRuntimeVisibleAnnotation.putAnnotations(
457+
symbolTable.addConstantUtf8(Constants.RUNTIME_VISIBLE_ANNOTATIONS), output);
458+
}
459+
if (lastRuntimeInvisibleAnnotation != null) {
460+
lastRuntimeInvisibleAnnotation.putAnnotations(
461+
symbolTable.addConstantUtf8(Constants.RUNTIME_INVISIBLE_ANNOTATIONS), output);
462+
}
463+
if (lastRuntimeVisibleTypeAnnotation != null) {
464+
lastRuntimeVisibleTypeAnnotation.putAnnotations(
465+
symbolTable.addConstantUtf8(Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS), output);
466+
}
467+
if (lastRuntimeInvisibleTypeAnnotation != null) {
468+
lastRuntimeInvisibleTypeAnnotation.putAnnotations(
469+
symbolTable.addConstantUtf8(Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS), output);
470+
}
471+
}
472+
338473
/**
339474
* Returns the size of a Runtime[In]VisibleParameterAnnotations attribute containing all the
340475
* annotation lists from the given AnnotationWriter sub-array. Also adds the attribute name to the

0 commit comments

Comments
 (0)