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 6c355c65b7..ccb7e21ecc 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassReader.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassReader.java @@ -160,7 +160,9 @@ public class ClassReader { * @param classFileLength the length in bytes of the ClassFile to be read. */ public ClassReader( - final byte[] classFileBuffer, final int classFileOffset, final int classFileLength) { + final byte[] classFileBuffer, + final int classFileOffset, + final int classFileLength) { // NOPMD(UnusedFormalParameter) used for backward compatibility. this(classFileBuffer, classFileOffset, /* checkClassVersion = */ true); } @@ -500,9 +502,8 @@ public class ClassReader { moduleMainClass = readClass(currentAttributeOffset, charBuffer); } else if (Constants.MODULE_PACKAGES.equals(attributeName)) { modulePackagesOffset = currentAttributeOffset; - } else if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) { - // This attribute is read in the constructor. - } else { + } else if (!Constants.BOOTSTRAP_METHODS.equals(attributeName)) { + // The BootstrapMethods attribute is read in the constructor. Attribute attribute = readAttribute( attributePrototypes, @@ -2358,12 +2359,12 @@ public class ClassReader { // Visit the local variable type annotations of the RuntimeVisibleTypeAnnotations attribute. if (visibleTypeAnnotationOffsets != null) { - for (int i = 0; i < visibleTypeAnnotationOffsets.length; ++i) { - int targetType = readByte(visibleTypeAnnotationOffsets[i]); + for (int typeAnnotationOffset : visibleTypeAnnotationOffsets) { + int targetType = readByte(typeAnnotationOffset); if (targetType == TypeReference.LOCAL_VARIABLE || targetType == TypeReference.RESOURCE_VARIABLE) { // Parse the target_type, target_info and target_path fields. - currentOffset = readTypeAnnotationTarget(context, visibleTypeAnnotationOffsets[i]); + currentOffset = readTypeAnnotationTarget(context, typeAnnotationOffset); // Parse the type_index field. String annotationDescriptor = readUTF8(currentOffset, charBuffer); currentOffset += 2; @@ -2386,12 +2387,12 @@ public class ClassReader { // Visit the local variable type annotations of the RuntimeInvisibleTypeAnnotations attribute. if (invisibleTypeAnnotationOffsets != null) { - for (int i = 0; i < invisibleTypeAnnotationOffsets.length; ++i) { - int targetType = readByte(invisibleTypeAnnotationOffsets[i]); + for (int typeAnnotationOffset : invisibleTypeAnnotationOffsets) { + int targetType = readByte(typeAnnotationOffset); if (targetType == TypeReference.LOCAL_VARIABLE || targetType == TypeReference.RESOURCE_VARIABLE) { // Parse the target_type, target_info and target_path fields. - currentOffset = readTypeAnnotationTarget(context, invisibleTypeAnnotationOffsets[i]); + currentOffset = readTypeAnnotationTarget(context, typeAnnotationOffset); // Parse the type_index field. String annotationDescriptor = readUTF8(currentOffset, charBuffer); currentOffset += 2; @@ -3283,9 +3284,9 @@ public class ClassReader { final char[] charBuffer, final int codeAttributeOffset, final Label[] labels) { - for (int i = 0; i < attributePrototypes.length; ++i) { - if (attributePrototypes[i].type.equals(type)) { - return attributePrototypes[i].read( + for (Attribute attributePrototype : attributePrototypes) { + if (attributePrototype.type.equals(type)) { + return attributePrototype.read( this, offset, length, charBuffer, codeAttributeOffset, labels); } } 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 1bf78de2d3..d383735a75 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassWriter.java @@ -383,10 +383,9 @@ public class ClassWriter extends ClassVisitor { innerClasses.putShort(innerName == null ? 0 : symbolTable.addConstantUtf8(innerName)); innerClasses.putShort(access); nameSymbol.info = numberOfInnerClasses; - } else { - // Compare the inner classes entry nameSymbol.info - 1 with the arguments of this method and - // throw an exception if there is a difference? } + // Else, compare the inner classes entry nameSymbol.info - 1 with the arguments of this method + // and throw an exception if there is a difference? } @Override diff --git a/spring-core/src/main/java/org/springframework/asm/ConstantDynamic.java b/spring-core/src/main/java/org/springframework/asm/ConstantDynamic.java index bb5a65563f..9174dbab5c 100644 --- a/spring-core/src/main/java/org/springframework/asm/ConstantDynamic.java +++ b/spring-core/src/main/java/org/springframework/asm/ConstantDynamic.java @@ -99,13 +99,36 @@ public final class ConstantDynamic { } /** - * Returns the arguments to pass to the bootstrap method, in order to compute the value of this + * Returns the number of arguments passed to the bootstrap method, in order to compute the value + * of this constant. + * + * @return the number of arguments passed to the bootstrap method, in order to compute the value + * of this constant. + */ + public int getBootstrapMethodArgumentCount() { + return bootstrapMethodArguments.length; + } + + /** + * Returns an argument passed to the bootstrap method, in order to compute the value of this * constant. * + * @param index an argument index, between 0 and {@link #getBootstrapMethodArgumentCount()} + * (exclusive). + * @return the argument passed to the bootstrap method, with the given index. + */ + public Object getBootstrapMethodArgument(final int index) { + return bootstrapMethodArguments[index]; + } + + /** + * Returns the arguments to pass to the bootstrap method, in order to compute the value of this + * constant. WARNING: this array must not be modified, and must not be returned to the user. + * * @return the arguments to pass to the bootstrap method, in order to compute the value of this * constant. */ - public Object[] getBootstrapMethodArguments() { + Object[] getBootstrapMethodArgumentsUnsafe() { return bootstrapMethodArguments; } diff --git a/spring-core/src/main/java/org/springframework/asm/MethodWriter.java b/spring-core/src/main/java/org/springframework/asm/MethodWriter.java index d2b844c5c7..7719a2db90 100644 --- a/spring-core/src/main/java/org/springframework/asm/MethodWriter.java +++ b/spring-core/src/main/java/org/springframework/asm/MethodWriter.java @@ -765,11 +765,10 @@ final class MethodWriter extends MethodVisitor { if (type == Opcodes.F_NEW) { currentBasicBlock.frame.setInputFrameFromApiFormat( symbolTable, numLocal, local, numStack, stack); - } else { - // In this case type is equal to F_INSERT by hypothesis, and currentBlock.frame contains - // the stack map frame at the current instruction, computed from the last F_NEW frame - // and the bytecode instructions in between (via calls to CurrentFrame#execute). } + // If type is not F_NEW then it is F_INSERT by hypothesis, and currentBlock.frame contains + // the stack map frame at the current instruction, computed from the last F_NEW frame and + // the bytecode instructions in between (via calls to CurrentFrame#execute). currentBasicBlock.frame.accept(this); } } else if (type == Opcodes.F_NEW) { @@ -1951,6 +1950,7 @@ final class MethodWriter extends MethodVisitor { putAbstractTypes(3, 3 + numLocal); stackMapTableEntries.putShort(numStack); putAbstractTypes(3 + numLocal, 3 + numLocal + numStack); + break; } } diff --git a/spring-core/src/main/java/org/springframework/asm/SymbolTable.java b/spring-core/src/main/java/org/springframework/asm/SymbolTable.java index 4294fb6a35..48a2802d7c 100644 --- a/spring-core/src/main/java/org/springframework/asm/SymbolTable.java +++ b/spring-core/src/main/java/org/springframework/asm/SymbolTable.java @@ -496,7 +496,7 @@ final class SymbolTable { constantDynamic.getName(), constantDynamic.getDescriptor(), constantDynamic.getBootstrapMethod(), - constantDynamic.getBootstrapMethodArguments()); + constantDynamic.getBootstrapMethodArgumentsUnsafe()); } else { throw new IllegalArgumentException("value " + value); } 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 52676cefb5..f4ef203986 100644 --- a/spring-core/src/main/java/org/springframework/asm/Type.java +++ b/spring-core/src/main/java/org/springframework/asm/Type.java @@ -37,7 +37,7 @@ import java.lang.reflect.Method; * @author Eric Bruneton * @author Chris Nokleberg */ -public class Type { +public final class Type { /** The sort of the {@code void} type. See {@link #getSort}. */ public static final int VOID = 0; @@ -153,7 +153,7 @@ public class Type { * @param valueBuffer a buffer containing the value of this field or method type. * @param valueBegin the beginning index, inclusive, of the value of this field or method type in * valueBuffer. - * @param valueEnd tne end index, exclusive, of the value of this field or method type in + * @param valueEnd the end index, exclusive, of the value of this field or method type in * valueBuffer. */ private Type(final int sort, final String valueBuffer, final int valueBegin, final int valueEnd) { @@ -304,9 +304,8 @@ public class Type { currentOffset++; } if (methodDescriptor.charAt(currentOffset++) == 'L') { - while (methodDescriptor.charAt(currentOffset++) != ';') { - // Skip the argument descriptor content. - } + // Skip the argument descriptor content. + currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1; } ++numArgumentTypes; } @@ -323,9 +322,8 @@ public class Type { currentOffset++; } if (methodDescriptor.charAt(currentOffset++) == 'L') { - while (methodDescriptor.charAt(currentOffset++) != ';') { - // Skip the argument descriptor content. - } + // Skip the argument descriptor content. + currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1; } argumentTypes[currentArgumentTypeIndex++] = getTypeInternal(methodDescriptor, currentArgumentTypeOffset, currentOffset); @@ -373,9 +371,8 @@ public class Type { currentOffset++; } if (methodDescriptor.charAt(currentOffset++) == 'L') { - while (methodDescriptor.charAt(currentOffset++) != ';') { - // Skip the argument descriptor content. - } + // Skip the argument descriptor content. + currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1; } } return getTypeInternal(methodDescriptor, currentOffset + 1, methodDescriptor.length()); @@ -508,11 +505,11 @@ public class Type { if (sort == OBJECT) { return valueBuffer.substring(valueBegin - 1, valueEnd + 1); } else if (sort == INTERNAL) { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append('L'); - stringBuilder.append(valueBuffer, valueBegin, valueEnd); - stringBuilder.append(';'); - return stringBuilder.toString(); + return new StringBuilder() + .append('L') + .append(valueBuffer, valueBegin, valueEnd) + .append(';') + .toString(); } else { return valueBuffer.substring(valueBegin, valueEnd); } @@ -540,8 +537,8 @@ public class Type { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append('('); Class[] parameters = constructor.getParameterTypes(); - for (int i = 0; i < parameters.length; ++i) { - appendDescriptor(parameters[i], stringBuilder); + for (Class parameter : parameters) { + appendDescriptor(parameter, stringBuilder); } return stringBuilder.append(")V").toString(); } @@ -556,8 +553,8 @@ public class Type { public static String getMethodDescriptor(final Type returnType, final Type... argumentTypes) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append('('); - for (int i = 0; i < argumentTypes.length; ++i) { - argumentTypes[i].appendDescriptor(stringBuilder); + for (Type argumentType : argumentTypes) { + argumentType.appendDescriptor(stringBuilder); } stringBuilder.append(')'); returnType.appendDescriptor(stringBuilder); @@ -574,8 +571,8 @@ public class Type { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append('('); Class[] parameters = method.getParameterTypes(); - for (int i = 0; i < parameters.length; ++i) { - appendDescriptor(parameters[i], stringBuilder); + for (Class parameter : parameters) { + appendDescriptor(parameter, stringBuilder); } stringBuilder.append(')'); appendDescriptor(method.getReturnType(), stringBuilder); @@ -591,9 +588,7 @@ public class Type { if (sort == OBJECT) { stringBuilder.append(valueBuffer, valueBegin - 1, valueEnd + 1); } else if (sort == INTERNAL) { - stringBuilder.append('L'); - stringBuilder.append(valueBuffer, valueBegin, valueEnd); - stringBuilder.append(';'); + stringBuilder.append('L').append(valueBuffer, valueBegin, valueEnd).append(';'); } else { stringBuilder.append(valueBuffer, valueBegin, valueEnd); } @@ -741,9 +736,8 @@ public class Type { currentOffset++; } if (methodDescriptor.charAt(currentOffset++) == 'L') { - while (methodDescriptor.charAt(currentOffset++) != ';') { - // Skip the argument descriptor content. - } + // Skip the argument descriptor content. + currentOffset = methodDescriptor.indexOf(';', currentOffset) + 1; } argumentsSize += 1; } diff --git a/spring-core/src/main/java/org/springframework/asm/TypePath.java b/spring-core/src/main/java/org/springframework/asm/TypePath.java index 12eeed43b7..b7cf845e7a 100644 --- a/spring-core/src/main/java/org/springframework/asm/TypePath.java +++ b/spring-core/src/main/java/org/springframework/asm/TypePath.java @@ -34,7 +34,7 @@ package org.springframework.asm; * * @author Eric Bruneton */ -public class TypePath { +public final class TypePath { /** A type path step that steps into the element type of an array type. See {@link #getStep}. */ public static final int ARRAY_ELEMENT = 0;