diff --git a/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java b/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java index 05b4f9ba2f..19e93382fd 100644 --- a/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java @@ -82,6 +82,17 @@ public abstract class AnnotationVisitor { this.av = annotationVisitor; } + /** + * The annotation visitor to which this visitor must delegate method calls. May be {@literal + * null}. + * + * @return the annotation visitor to which this visitor must delegate method calls, or {@literal + * null}. + */ + public AnnotationVisitor getDelegate() { + return av; + } + /** * Visits a primitive value of the annotation. * diff --git a/spring-core/src/main/java/org/springframework/asm/ClassReader.java b/spring-core/src/main/java/org/springframework/asm/ClassReader.java index 725ba340bb..d84485cafd 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassReader.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassReader.java @@ -194,7 +194,7 @@ public class ClassReader { this.b = classFileBuffer; // Check the class' major_version. This field is after the magic and minor_version fields, which // use 4 and 2 bytes respectively. - if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V19) { + if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V21) { throw new IllegalArgumentException( "Unsupported class file major version " + readShort(classFileOffset + 6)); } @@ -308,6 +308,7 @@ public class ClassReader { * @return the content of the given input stream. * @throws IOException if a problem occurs during reading. */ + @SuppressWarnings("PMD.UseTryWithResources") private static byte[] readStream(final InputStream inputStream, final boolean close) throws IOException { if (inputStream == null) { @@ -376,7 +377,7 @@ public class ClassReader { } /** - * Returns the internal of name of the super class (see {@link Type#getInternalName()}). For + * Returns the internal name of the super class (see {@link Type#getInternalName()}). For * interfaces, the super class is {@link Object}. * * @return the internal name of the super class, or {@literal null} for {@link Object} class. diff --git a/spring-core/src/main/java/org/springframework/asm/ClassTooLargeException.java b/spring-core/src/main/java/org/springframework/asm/ClassTooLargeException.java index f679328b87..bc6a96dede 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassTooLargeException.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassTooLargeException.java @@ -42,7 +42,8 @@ public final class ClassTooLargeException extends IndexOutOfBoundsException { /** * Constructs a new {@link ClassTooLargeException}. * - * @param className the internal name of the class. + * @param className the internal name of the class (see {@link + * org.objectweb.asm.Type#getInternalName()}). * @param constantPoolCount the number of constant pool items of the class. */ public ClassTooLargeException(final String className, final int constantPoolCount) { @@ -52,7 +53,7 @@ public final class ClassTooLargeException extends IndexOutOfBoundsException { } /** - * Returns the internal name of the class. + * Returns the internal name of the class (see {@link org.objectweb.asm.Type#getInternalName()}). * * @return the internal name of the class. */ diff --git a/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java b/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java index 14064e742e..80d241dddd 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassVisitor.java @@ -81,6 +81,15 @@ public abstract class ClassVisitor { this.cv = classVisitor; } + /** + * The class visitor to which this visitor must delegate method calls. May be {@literal null}. + * + * @return the class visitor to which this visitor must delegate method calls, or {@literal null}. + */ + public ClassVisitor getDelegate() { + return cv; + } + /** * Visits the header of the class. * @@ -155,7 +164,8 @@ public abstract class ClassVisitor { * implicitly its own nest, so it's invalid to call this method with the visited class name as * argument. * - * @param nestHost the internal name of the host class of the nest. + * @param nestHost the internal name of the host class of the nest (see {@link + * Type#getInternalName()}). */ public void visitNestHost(final String nestHost) { if (api < Opcodes.ASM7) { @@ -167,14 +177,19 @@ public abstract class ClassVisitor { } /** - * Visits the enclosing class of the class. This method must be called only if the class has an - * enclosing class. + * Visits the enclosing class of the class. This method must be called only if this class is a + * local or anonymous class. See the JVMS 4.7.7 section for more details. * - * @param owner internal name of the enclosing class of the class. + * @param owner internal name of the enclosing class of the class (see {@link + * Type#getInternalName()}). * @param name the name of the method that contains the class, or {@literal null} if the class is - * not enclosed in a method of its enclosing class. + * not enclosed in a method or constructor of its enclosing class (e.g. if it is enclosed in + * an instance initializer, static initializer, instance variable initializer, or class + * variable initializer). * @param descriptor the descriptor of the method that contains the class, or {@literal null} if - * the class is not enclosed in a method of its enclosing class. + * the class is not enclosed in a method or constructor of its enclosing class (e.g. if it is + * enclosed in an instance initializer, static initializer, instance variable initializer, or + * class variable initializer). */ public void visitOuterClass(final String owner, final String name, final String descriptor) { if (cv != null) { @@ -241,7 +256,7 @@ public abstract class ClassVisitor { * the visited class is the host of a nest. A nest host is implicitly a member of its own nest, so * it's invalid to call this method with the visited class name as argument. * - * @param nestMember the internal name of a nest member. + * @param nestMember the internal name of a nest member (see {@link Type#getInternalName()}). */ public void visitNestMember(final String nestMember) { if (api < Opcodes.ASM7) { @@ -256,7 +271,8 @@ public abstract class ClassVisitor { * Visits a permitted subclasses. A permitted subclass is one of the allowed subclasses of the * current class. * - * @param permittedSubclass the internal name of a permitted subclass. + * @param permittedSubclass the internal name of a permitted subclass (see {@link + * Type#getInternalName()}). */ public void visitPermittedSubclass(final String permittedSubclass) { if (api < Opcodes.ASM9) { @@ -269,15 +285,18 @@ public abstract class ClassVisitor { /** * Visits information about an inner class. This inner class is not necessarily a member of the - * class being visited. + * class being visited. More precisely, every class or interface C which is referenced by this + * class and which is not a package member must be visited with this method. This class must + * reference its nested class or interface members, and its enclosing class, if any. See the JVMS + * 4.7.6 section for more details. * - * @param name the internal name of an inner class (see {@link Type#getInternalName()}). - * @param outerName the internal name of the class to which the inner class belongs (see {@link - * Type#getInternalName()}). May be {@literal null} for not member classes. - * @param innerName the (simple) name of the inner class inside its enclosing class. May be - * {@literal null} for anonymous inner classes. - * @param access the access flags of the inner class as originally declared in the enclosing - * class. + * @param name the internal name of C (see {@link Type#getInternalName()}). + * @param outerName the internal name of the class or interface C is a member of (see {@link + * Type#getInternalName()}). Must be {@literal null} if C is not the member of a class or + * interface (e.g. for local or anonymous classes). + * @param innerName the (simple) name of C. Must be {@literal null} for anonymous inner classes. + * @param access the access flags of C originally declared in the source code from which this + * class was compiled. */ public void visitInnerClass( final String name, final String outerName, final String innerName, final int access) { diff --git a/spring-core/src/main/java/org/springframework/asm/ClassWriter.java b/spring-core/src/main/java/org/springframework/asm/ClassWriter.java index 045d571312..030d86566f 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassWriter.java @@ -842,7 +842,7 @@ public class ClassWriter extends ClassVisitor { * constant pool already contains a similar item. This method is intended for {@link Attribute} * sub classes, and is normally not needed by class generators or adapters. * - * @param value the internal name of the class. + * @param value the internal name of the class (see {@link Type#getInternalName()}). * @return the index of a new or already existing class reference item. */ public int newClass(final String value) { @@ -894,7 +894,8 @@ public class ClassWriter extends ClassVisitor { * Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link * Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. - * @param owner the internal name of the field or method owner class. + * @param owner the internal name of the field or method owner class (see {@link + * Type#getInternalName()}). * @param name the name of the field or method. * @param descriptor the descriptor of the field or method. * @return the index of a new or already existing method type reference item. @@ -916,7 +917,8 @@ public class ClassWriter extends ClassVisitor { * Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link * Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. - * @param owner the internal name of the field or method owner class. + * @param owner the internal name of the field or method owner class (see {@link + * Type#getInternalName()}). * @param name the name of the field or method. * @param descriptor the descriptor of the field or method. * @param isInterface true if the owner is an interface. @@ -978,7 +980,7 @@ public class ClassWriter extends ClassVisitor { * constant pool already contains a similar item. This method is intended for {@link Attribute} * sub classes, and is normally not needed by class generators or adapters. * - * @param owner the internal name of the field's owner class. + * @param owner the internal name of the field's owner class (see {@link Type#getInternalName()}). * @param name the field's name. * @param descriptor the field's descriptor. * @return the index of a new or already existing field reference item. @@ -992,7 +994,8 @@ public class ClassWriter extends ClassVisitor { * constant pool already contains a similar item. This method is intended for {@link Attribute} * sub classes, and is normally not needed by class generators or adapters. * - * @param owner the internal name of the method's owner class. + * @param owner the internal name of the method's owner class (see {@link + * Type#getInternalName()}). * @param name the method's name. * @param descriptor the method's descriptor. * @param isInterface {@literal true} if {@code owner} is an interface. @@ -1028,9 +1031,10 @@ public class ClassWriter extends ClassVisitor { * currently being generated by this ClassWriter, which can of course not be loaded since it is * under construction. * - * @param type1 the internal name of a class. - * @param type2 the internal name of another class. - * @return the internal name of the common super class of the two given classes. + * @param type1 the internal name of a class (see {@link Type#getInternalName()}). + * @param type2 the internal name of another class (see {@link Type#getInternalName()}). + * @return the internal name of the common super class of the two given classes (see {@link + * Type#getInternalName()}). */ protected String getCommonSuperClass(final String type1, final String type2) { ClassLoader classLoader = getClassLoader(); diff --git a/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java b/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java index 2aa16bc8e6..676843656f 100644 --- a/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/FieldVisitor.java @@ -78,6 +78,15 @@ public abstract class FieldVisitor { this.fv = fieldVisitor; } + /** + * The field visitor to which this visitor must delegate method calls. May be {@literal null}. + * + * @return the field visitor to which this visitor must delegate method calls, or {@literal null}. + */ + public FieldVisitor getDelegate() { + return fv; + } + /** * Visits an annotation of the field. * diff --git a/spring-core/src/main/java/org/springframework/asm/Frame.java b/spring-core/src/main/java/org/springframework/asm/Frame.java index 5a1dc2ffb1..76317cc91c 100644 --- a/spring-core/src/main/java/org/springframework/asm/Frame.java +++ b/spring-core/src/main/java/org/springframework/asm/Frame.java @@ -367,11 +367,12 @@ class Frame { typeValue = REFERENCE_KIND | symbolTable.addType(internalName); break; default: - throw new IllegalArgumentException(); + throw new IllegalArgumentException( + "Invalid descriptor fragment: " + buffer.substring(elementDescriptorOffset)); } return ((elementDescriptorOffset - offset) << DIM_SHIFT) | typeValue; default: - throw new IllegalArgumentException(); + throw new IllegalArgumentException("Invalid descriptor: " + buffer.substring(offset)); } } diff --git a/spring-core/src/main/java/org/springframework/asm/Handle.java b/spring-core/src/main/java/org/springframework/asm/Handle.java index 52a3e316bf..717be9b82b 100644 --- a/spring-core/src/main/java/org/springframework/asm/Handle.java +++ b/spring-core/src/main/java/org/springframework/asm/Handle.java @@ -65,7 +65,7 @@ public final class Handle { * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link * Opcodes#H_INVOKEINTERFACE}. * @param owner the internal name of the class that owns the field or method designated by this - * handle. + * handle (see {@link Type#getInternalName()}). * @param name the name of the field or method designated by this handle. * @param descriptor the descriptor of the field or method designated by this handle. * @deprecated this constructor has been superseded by {@link #Handle(int, String, String, String, @@ -85,7 +85,7 @@ public final class Handle { * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link * Opcodes#H_INVOKEINTERFACE}. * @param owner the internal name of the class that owns the field or method designated by this - * handle. + * handle (see {@link Type#getInternalName()}). * @param name the name of the field or method designated by this handle. * @param descriptor the descriptor of the field or method designated by this handle. * @param isInterface whether the owner is an interface or not. @@ -118,7 +118,8 @@ public final class Handle { /** * Returns the internal name of the class that owns the field or method designated by this handle. * - * @return the internal name of the class that owns the field or method designated by this handle. + * @return the internal name of the class that owns the field or method designated by this handle + * (see {@link Type#getInternalName()}). */ public String getOwner() { return owner; diff --git a/spring-core/src/main/java/org/springframework/asm/MethodTooLargeException.java b/spring-core/src/main/java/org/springframework/asm/MethodTooLargeException.java index ac263c442a..b41ec8b588 100644 --- a/spring-core/src/main/java/org/springframework/asm/MethodTooLargeException.java +++ b/spring-core/src/main/java/org/springframework/asm/MethodTooLargeException.java @@ -44,7 +44,7 @@ public final class MethodTooLargeException extends IndexOutOfBoundsException { /** * Constructs a new {@link MethodTooLargeException}. * - * @param className the internal name of the owner class. + * @param className the internal name of the owner class (see {@link Type#getInternalName()}). * @param methodName the name of the method. * @param descriptor the descriptor of the method. * @param codeSize the size of the method's Code attribute, in bytes. @@ -64,7 +64,7 @@ public final class MethodTooLargeException extends IndexOutOfBoundsException { /** * Returns the internal name of the owner class. * - * @return the internal name of the owner class. + * @return the internal name of the owner class (see {@link Type#getInternalName()}). */ public String getClassName() { return className; diff --git a/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java b/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java index 35ecb14c4e..35ffc81576 100644 --- a/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java @@ -94,6 +94,16 @@ public abstract class MethodVisitor { this.mv = methodVisitor; } + /** + * The method visitor to which this visitor must delegate method calls. May be {@literal null}. + * + * @return the method visitor to which this visitor must delegate method calls, or {@literal + * null}. + */ + public MethodVisitor getDelegate() { + return mv; + } + // ----------------------------------------------------------------------------------------------- // Parameters, annotations and non standard attributes // ----------------------------------------------------------------------------------------------- @@ -120,7 +130,7 @@ public abstract class MethodVisitor { * @return a visitor to the visit the actual default value of this annotation interface method, or * {@literal null} if this visitor is not interested in visiting this default value. The * 'name' parameters passed to the methods of this annotation visitor are ignored. Moreover, - * exacly one visit method must be called on this annotation visitor, followed by visitEnd. + * exactly one visit method must be called on this annotation visitor, followed by visitEnd. */ public AnnotationVisitor visitAnnotationDefault() { if (mv != null) { @@ -273,15 +283,17 @@ public abstract class MethodVisitor { * @param type the type of this stack map frame. Must be {@link Opcodes#F_NEW} for expanded * frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link * Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames. - * @param numLocal the number of local variables in the visited frame. + * @param numLocal the number of local variables in the visited frame. Long and double values + * count for one variable. * @param local the local variable types in this frame. This array must not be modified. Primitive * types are represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link * Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL} or * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a single element). - * Reference types are represented by String objects (representing internal names), and - * uninitialized types by Label objects (this label designates the NEW instruction that - * created this uninitialized value). - * @param numStack the number of operand stack elements in the visited frame. + * Reference types are represented by String objects (representing internal names, see {@link + * Type#getInternalName()}), and uninitialized types by Label objects (this label designates + * the NEW instruction that created this uninitialized value). + * @param numStack the number of operand stack elements in the visited frame. Long and double + * values count for one stack element. * @param stack the operand stack types in this frame. This array must not be modified. Its * content has the same format as the "local" array. * @throws IllegalStateException if a frame is visited just after another one, without any @@ -360,7 +372,7 @@ public abstract class MethodVisitor { /** * Visits a type instruction. A type instruction is an instruction that takes the internal name of - * a class as parameter. + * a class as parameter (see {@link Type#getInternalName()}). * * @param opcode the opcode of the type instruction to be visited. This opcode is either NEW, * ANEWARRAY, CHECKCAST or INSTANCEOF. @@ -552,12 +564,12 @@ public abstract class MethodVisitor { /** * Visits an IINC instruction. * - * @param var index of the local variable to be incremented. + * @param varIndex index of the local variable to be incremented. * @param increment amount to increment the local variable by. */ - public void visitIincInsn(final int var, final int increment) { + public void visitIincInsn(final int varIndex, final int increment) { if (mv != null) { - mv.visitIincInsn(var, increment); + mv.visitIincInsn(varIndex, increment); } } @@ -643,8 +655,9 @@ public abstract class MethodVisitor { * @param start the beginning of the exception handler's scope (inclusive). * @param end the end of the exception handler's scope (exclusive). * @param handler the beginning of the exception handler's code. - * @param type the internal name of the type of exceptions handled by the handler, or {@literal - * null} to catch any exceptions (for "finally" blocks). + * @param type the internal name of the type of exceptions handled by the handler (see {@link + * Type#getInternalName()}), or {@literal null} to catch any exceptions (for "finally" + * blocks). * @throws IllegalArgumentException if one of the labels has already been visited by this visitor * (by the {@link #visitLabel} method). */ diff --git a/spring-core/src/main/java/org/springframework/asm/Opcodes.java b/spring-core/src/main/java/org/springframework/asm/Opcodes.java index dc7bbce285..035aa45484 100644 --- a/spring-core/src/main/java/org/springframework/asm/Opcodes.java +++ b/spring-core/src/main/java/org/springframework/asm/Opcodes.java @@ -284,6 +284,8 @@ public interface Opcodes { int V17 = 0 << 16 | 61; int V18 = 0 << 16 | 62; int V19 = 0 << 16 | 63; + int V20 = 0 << 16 | 64; + int V21 = 0 << 16 | 65; /** * Version flag indicating that the class is using 'preview' features. diff --git a/spring-core/src/main/java/org/springframework/asm/RecordComponentVisitor.java b/spring-core/src/main/java/org/springframework/asm/RecordComponentVisitor.java index 6e767b6e70..9832b25cf0 100644 --- a/spring-core/src/main/java/org/springframework/asm/RecordComponentVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/RecordComponentVisitor.java @@ -45,7 +45,7 @@ public abstract class RecordComponentVisitor { /** * The record visitor to which this visitor must delegate method calls. May be {@literal null}. */ - /*package-private*/ RecordComponentVisitor delegate; + protected RecordComponentVisitor delegate; /** * Constructs a new {@link RecordComponentVisitor}. @@ -83,7 +83,8 @@ public abstract class RecordComponentVisitor { /** * The record visitor to which this visitor must delegate method calls. May be {@literal null}. * - * @return the record visitor to which this visitor must delegate method calls or {@literal null}. + * @return the record visitor to which this visitor must delegate method calls, or {@literal + * null}. */ public RecordComponentVisitor getDelegate() { return delegate; diff --git a/spring-core/src/main/java/org/springframework/asm/Type.java b/spring-core/src/main/java/org/springframework/asm/Type.java index 24d0e679b8..36d69ab8b0 100644 --- a/spring-core/src/main/java/org/springframework/asm/Type.java +++ b/spring-core/src/main/java/org/springframework/asm/Type.java @@ -245,7 +245,7 @@ public final class Type { /** * Returns the {@link Type} corresponding to the given internal name. * - * @param internalName an internal name. + * @param internalName an internal name (see {@link Type#getInternalName()}). * @return the {@link Type} corresponding to the given internal name. */ public static Type getObjectType(final String internalName) { @@ -708,8 +708,8 @@ public final class Type { * * @return the size of the arguments of the method (plus one for the implicit this argument), * argumentsSize, and the size of its return value, returnSize, packed into a single int i = - * {@code (argumentsSize << 2) | returnSize} (argumentsSize is therefore equal to {@code - * i >> 2}, and returnSize to {@code i & 0x03}). + * {@code (argumentsSize << 2) | returnSize} (argumentsSize is therefore equal to {@code + * i >> 2}, and returnSize to {@code i & 0x03}). */ public int getArgumentsAndReturnSizes() { return getArgumentsAndReturnSizes(getDescriptor()); @@ -721,8 +721,8 @@ public final class Type { * @param methodDescriptor a method descriptor. * @return the size of the arguments of the method (plus one for the implicit this argument), * argumentsSize, and the size of its return value, returnSize, packed into a single int i = - * {@code (argumentsSize << 2) | returnSize} (argumentsSize is therefore equal to {@code - * i >> 2}, and returnSize to {@code i & 0x03}). + * {@code (argumentsSize << 2) | returnSize} (argumentsSize is therefore equal to {@code + * i >> 2}, and returnSize to {@code i & 0x03}). */ public static int getArgumentsAndReturnSizes(final String methodDescriptor) { int argumentsSize = 1;