Skip to content

Commit

Permalink
Upgrade to ASM 7.1
Browse files Browse the repository at this point in the history
Closes gh-22503
  • Loading branch information
jhoeller committed Mar 8, 2019
1 parent a06ab6d commit f5248ff
Show file tree
Hide file tree
Showing 16 changed files with 841 additions and 541 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ public abstract class AnnotationVisitor {
*/
protected final int api;

/** The annotation visitor to which this visitor must delegate method calls. May be null. */
/**
* The annotation visitor to which this visitor must delegate method calls. May be {@literal
* null}.
*/
protected AnnotationVisitor av;

/**
Expand All @@ -62,11 +65,11 @@ public AnnotationVisitor(final int api) {
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
* @param annotationVisitor the annotation visitor to which this visitor must delegate method
* calls. May be null.
* calls. May be {@literal null}.
*/
public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) {
if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) {
throw new IllegalArgumentException();
if (api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4) {
throw new IllegalArgumentException("Unsupported api " + api);
}
this.api = api;
this.av = annotationVisitor;
Expand Down
163 changes: 149 additions & 14 deletions spring-core/src/main/java/org/springframework/asm/AnnotationWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ final class AnnotationWriter extends AnnotationVisitor {
private AnnotationWriter nextAnnotation;

// -----------------------------------------------------------------------------------------------
// Constructors
// Constructors and factories
// -----------------------------------------------------------------------------------------------

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

/**
* Constructs a new {@link AnnotationWriter} using named values.
* Creates a new {@link AnnotationWriter} using named values.
*
* @param symbolTable where the constants used in this AnnotationWriter must be stored.
* @param annotation where the 'annotation' or 'type_annotation' JVMS structure corresponding to
* the visited content must be stored. This ByteVector must already contain all the fields of
* the structure except the last one (the element_value_pairs array).
* @param descriptor the class descriptor of the annotation class.
* @param previousAnnotation the previously visited annotation of the
* Runtime[In]Visible[Type]Annotations attribute to which this annotation belongs, or null in
* other cases (e.g. nested or array annotations).
* Runtime[In]Visible[Type]Annotations attribute to which this annotation belongs, or
* {@literal null} in other cases (e.g. nested or array annotations).
* @return a new {@link AnnotationWriter} for the given annotation descriptor.
*/
AnnotationWriter(
static AnnotationWriter create(
final SymbolTable symbolTable,
final ByteVector annotation,
final String descriptor,
final AnnotationWriter previousAnnotation) {
// Create a ByteVector to hold an 'annotation' JVMS structure.
// See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16.
ByteVector annotation = new ByteVector();
// Write type_index and reserve space for num_element_value_pairs.
annotation.putShort(symbolTable.addConstantUtf8(descriptor)).putShort(0);
return new AnnotationWriter(
symbolTable, /* useNamedValues = */ true, annotation, previousAnnotation);
}

/**
* Creates a new {@link AnnotationWriter} using named values.
*
* @param symbolTable where the constants used in this AnnotationWriter must be stored.
* @param typeRef a reference to the annotated type. The sort of this type reference must be
* {@link TypeReference#CLASS_TYPE_PARAMETER}, {@link
* TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See
* {@link TypeReference}.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
* 'typeRef' as a whole.
* @param descriptor the class descriptor of the annotation class.
* @param previousAnnotation the previously visited annotation of the
* Runtime[In]Visible[Type]Annotations attribute to which this annotation belongs, or
* {@literal null} in other cases (e.g. nested or array annotations).
* @return a new {@link AnnotationWriter} for the given type annotation reference and descriptor.
*/
static AnnotationWriter create(
final SymbolTable symbolTable,
final int typeRef,
final TypePath typePath,
final String descriptor,
final AnnotationWriter previousAnnotation) {
this(symbolTable, /* useNamedValues = */ true, annotation, previousAnnotation);
// Create a ByteVector to hold a 'type_annotation' JVMS structure.
// See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20.
ByteVector typeAnnotation = new ByteVector();
// Write target_type, target_info, and target_path.
TypeReference.putTarget(typeRef, typeAnnotation);
TypePath.put(typePath, typeAnnotation);
// Write type_index and reserve space for num_element_value_pairs.
typeAnnotation.putShort(symbolTable.addConstantUtf8(descriptor)).putShort(0);
return new AnnotationWriter(
symbolTable, /* useNamedValues = */ true, typeAnnotation, previousAnnotation);
}

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

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

/**
* Returns the size of the Runtime[In]Visible[Type]Annotations attributes containing the given
* annotations and all their <i>predecessors</i> (see {@link #previousAnnotation}. Also adds the
* attribute names to the constant pool of the class (if not null).
*
* @param lastRuntimeVisibleAnnotation The last runtime visible annotation of a field, method or
* class. The previous ones can be accessed with the {@link #previousAnnotation} field. May be
* {@literal null}.
* @param lastRuntimeInvisibleAnnotation The last runtime invisible annotation of this a field,
* method or class. The previous ones can be accessed with the {@link #previousAnnotation}
* field. May be {@literal null}.
* @param lastRuntimeVisibleTypeAnnotation The last runtime visible type annotation of this a
* field, method or class. The previous ones can be accessed with the {@link
* #previousAnnotation} field. May be {@literal null}.
* @param lastRuntimeInvisibleTypeAnnotation The last runtime invisible type annotation of a
* field, method or class field. The previous ones can be accessed with the {@link
* #previousAnnotation} field. May be {@literal null}.
* @return the size in bytes of a Runtime[In]Visible[Type]Annotations attribute containing the
* given annotations and all their predecessors. This includes the size of the
* attribute_name_index and attribute_length fields.
*/
static int computeAnnotationsSize(
final AnnotationWriter lastRuntimeVisibleAnnotation,
final AnnotationWriter lastRuntimeInvisibleAnnotation,
final AnnotationWriter lastRuntimeVisibleTypeAnnotation,
final AnnotationWriter lastRuntimeInvisibleTypeAnnotation) {
int size = 0;
if (lastRuntimeVisibleAnnotation != null) {
size +=
lastRuntimeVisibleAnnotation.computeAnnotationsSize(
Constants.RUNTIME_VISIBLE_ANNOTATIONS);
}
if (lastRuntimeInvisibleAnnotation != null) {
size +=
lastRuntimeInvisibleAnnotation.computeAnnotationsSize(
Constants.RUNTIME_INVISIBLE_ANNOTATIONS);
}
if (lastRuntimeVisibleTypeAnnotation != null) {
size +=
lastRuntimeVisibleTypeAnnotation.computeAnnotationsSize(
Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
}
if (lastRuntimeInvisibleTypeAnnotation != null) {
size +=
lastRuntimeInvisibleTypeAnnotation.computeAnnotationsSize(
Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
}
return size;
}

/**
* Puts a Runtime[In]Visible[Type]Annotations attribute containing this annotations and all its
* <i>predecessors</i> (see {@link #previousAnnotation} in the given ByteVector. Annotations are
Expand Down Expand Up @@ -335,6 +425,51 @@ void putAnnotations(final int attributeNameIndex, final ByteVector output) {
}
}

/**
* Puts the Runtime[In]Visible[Type]Annotations attributes containing the given annotations and
* all their <i>predecessors</i> (see {@link #previousAnnotation} in the given ByteVector.
* Annotations are put in the same order they have been visited.
*
* @param symbolTable where the constants used in the AnnotationWriter instances are stored.
* @param lastRuntimeVisibleAnnotation The last runtime visible annotation of a field, method or
* class. The previous ones can be accessed with the {@link #previousAnnotation} field. May be
* {@literal null}.
* @param lastRuntimeInvisibleAnnotation The last runtime invisible annotation of this a field,
* method or class. The previous ones can be accessed with the {@link #previousAnnotation}
* field. May be {@literal null}.
* @param lastRuntimeVisibleTypeAnnotation The last runtime visible type annotation of this a
* field, method or class. The previous ones can be accessed with the {@link
* #previousAnnotation} field. May be {@literal null}.
* @param lastRuntimeInvisibleTypeAnnotation The last runtime invisible type annotation of a
* field, method or class field. The previous ones can be accessed with the {@link
* #previousAnnotation} field. May be {@literal null}.
* @param output where the attributes must be put.
*/
static void putAnnotations(
final SymbolTable symbolTable,
final AnnotationWriter lastRuntimeVisibleAnnotation,
final AnnotationWriter lastRuntimeInvisibleAnnotation,
final AnnotationWriter lastRuntimeVisibleTypeAnnotation,
final AnnotationWriter lastRuntimeInvisibleTypeAnnotation,
final ByteVector output) {
if (lastRuntimeVisibleAnnotation != null) {
lastRuntimeVisibleAnnotation.putAnnotations(
symbolTable.addConstantUtf8(Constants.RUNTIME_VISIBLE_ANNOTATIONS), output);
}
if (lastRuntimeInvisibleAnnotation != null) {
lastRuntimeInvisibleAnnotation.putAnnotations(
symbolTable.addConstantUtf8(Constants.RUNTIME_INVISIBLE_ANNOTATIONS), output);
}
if (lastRuntimeVisibleTypeAnnotation != null) {
lastRuntimeVisibleTypeAnnotation.putAnnotations(
symbolTable.addConstantUtf8(Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS), output);
}
if (lastRuntimeInvisibleTypeAnnotation != null) {
lastRuntimeInvisibleTypeAnnotation.putAnnotations(
symbolTable.addConstantUtf8(Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS), output);
}
}

/**
* Returns the size of a Runtime[In]VisibleParameterAnnotations attribute containing all the
* annotation lists from the given AnnotationWriter sub-array. Also adds the attribute name to the
Expand Down
Loading

0 comments on commit f5248ff

Please sign in to comment.