diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java index 2d0fd41536208f398161780cc618cb08327ca183..793dd854da854d31b890897e9c66694b6e82c4a0 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java @@ -263,8 +263,7 @@ public class Analyzer implements Opcodes { List insnHandlers = handlers[insnIndex]; if (insnHandlers != null) { - for (int i = 0; i < insnHandlers.size(); ++i) { - TryCatchBlockNode tryCatchBlock = insnHandlers.get(i); + for (TryCatchBlockNode tryCatchBlock : insnHandlers) { Type catchType; if (tryCatchBlock.type == null) { catchType = Type.getObjectType("java/lang/Throwable"); @@ -348,8 +347,7 @@ public class Analyzer implements Opcodes { // Push the exception handler successors of currentInsn onto instructionIndicesToProcess. List insnHandlers = handlers[currentInsnIndex]; if (insnHandlers != null) { - for (int i = 0; i < insnHandlers.size(); ++i) { - TryCatchBlockNode tryCatchBlock = insnHandlers.get(i); + for (TryCatchBlockNode tryCatchBlock : insnHandlers) { instructionIndicesToProcess.add(insnList.indexOf(tryCatchBlock.handler)); } } @@ -393,12 +391,12 @@ public class Analyzer implements Opcodes { currentLocal++; } Type[] argumentTypes = Type.getArgumentTypes(method.desc); - for (int i = 0; i < argumentTypes.length; ++i) { + for (Type argumentType : argumentTypes) { frame.setLocal( currentLocal, - interpreter.newParameterValue(isInstanceMethod, currentLocal, argumentTypes[i])); + interpreter.newParameterValue(isInstanceMethod, currentLocal, argumentType)); currentLocal++; - if (argumentTypes[i].getSize() == 2) { + if (argumentType.getSize() == 2) { frame.setLocal(currentLocal, interpreter.newEmptyValue(currentLocal)); currentLocal++; } diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicValue.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicValue.java index 806b6326ce3d09d40b3e8741e102d65839faeab3..3486a48e3d69be1c3b989fd6eef782cf8b685123 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicValue.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicValue.java @@ -80,6 +80,7 @@ public class BasicValue implements Value { return type; } + @Override public int getSize() { return type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1; } diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java index b9a1ac192d047607e89d102ecb2e3363bb105fb8..72f68937ecb7151ad00795f734c290766504abba 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java @@ -375,9 +375,9 @@ public class BasicVerifier extends BasicInterpreter { throws AnalyzerException { int opcode = insn.getOpcode(); if (opcode == MULTIANEWARRAY) { - for (int i = 0; i < values.size(); ++i) { - if (!BasicValue.INT_VALUE.equals(values.get(i))) { - throw new AnalyzerException(insn, null, BasicValue.INT_VALUE, values.get(i)); + for (BasicValue value : values) { + if (!BasicValue.INT_VALUE.equals(value)) { + throw new AnalyzerException(insn, null, BasicValue.INT_VALUE, value); } } } else { diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java index 09ce437743140a1127bdea7c49587a70323bfb98..05870c83f0c2eca1d1c9567075845a7e0c8469f8 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java @@ -79,13 +79,13 @@ public class Frame { } /** - * Constructs a copy of the given. + * Constructs a copy of the given Frame. * * @param frame a frame. */ public Frame(final Frame frame) { this(frame.numLocals, frame.values.length - frame.numLocals); - init(frame); + init(frame); // NOPMD(ConstructorCallsOverridableMethod): can't fix for backward compatibility. } /** diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java index 91bf294dd318927733d91465a6da05417e82b25b..8361b907d10c27f9dffe80962b69a66f1a8767ce 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java @@ -291,7 +291,7 @@ public class SimpleVerifier extends BasicVerifier { * @return whether 'type' corresponds to an interface. */ protected boolean isInterface(final Type type) { - if (currentClass != null && type.equals(currentClass)) { + if (currentClass != null && currentClass.equals(type)) { return isInterface; } return getClass(type).isInterface(); @@ -306,7 +306,7 @@ public class SimpleVerifier extends BasicVerifier { * @return the type corresponding to the super class of 'type'. */ protected Type getSuperClass(final Type type) { - if (currentClass != null && type.equals(currentClass)) { + if (currentClass != null && currentClass.equals(type)) { return currentSuperClass; } Class superClass = getClass(type).getSuperclass(); @@ -329,7 +329,7 @@ public class SimpleVerifier extends BasicVerifier { if (type1.equals(type2)) { return true; } - if (currentClass != null && type1.equals(currentClass)) { + if (currentClass != null && currentClass.equals(type1)) { if (getSuperClass(type2) == null) { return false; } else { @@ -339,13 +339,12 @@ public class SimpleVerifier extends BasicVerifier { return isAssignableFrom(type1, getSuperClass(type2)); } } - if (currentClass != null && type2.equals(currentClass)) { + if (currentClass != null && currentClass.equals(type2)) { if (isAssignableFrom(type1, currentSuperClass)) { return true; } if (currentClassInterfaces != null) { - for (int i = 0; i < currentClassInterfaces.size(); ++i) { - Type currentClassInterface = currentClassInterfaces.get(i); + for (Type currentClassInterface : currentClassInterfaces) { if (isAssignableFrom(type1, currentClassInterface)) { return true; } diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SmallSet.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SmallSet.java index d9dbdbca164aa715a307c1e3763532cb099ad90b..597b73f8cf94e35716ce8892af47b461ed0a22f7 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SmallSet.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SmallSet.java @@ -168,10 +168,12 @@ final class SmallSet extends AbstractSet { this.secondElement = secondElement; } + @Override public boolean hasNext() { return firstElement != null; } + @Override public T next() { if (firstElement == null) { throw new NoSuchElementException(); diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java index 6a765e2ac5a09b7c2b17e2f5d37eab89446d8735..0b41ff2c4c9625a572cf5c430deb3dcf33957a2e 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java @@ -95,6 +95,7 @@ public class SourceInterpreter extends Interpreter implements Opcod break; default: size = 1; + break; } return new SourceValue(size, insn); } @@ -123,6 +124,7 @@ public class SourceInterpreter extends Interpreter implements Opcod break; default: size = 1; + break; } return new SourceValue(size, insn); } @@ -154,6 +156,7 @@ public class SourceInterpreter extends Interpreter implements Opcod break; default: size = 1; + break; } return new SourceValue(size, insn); } diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceValue.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceValue.java index 6e4922a1935900be65b030806ae2465a019d6dcd..9e007e3cbc2f449d3b78ebf8a300bc0f8466675c 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceValue.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceValue.java @@ -98,6 +98,7 @@ public class SourceValue implements Value { * @return the size of this value, in 32 bits words. This size is 1 for byte, boolean, char, * short, int, float, object and array types, and 2 for long and double. */ + @Override public int getSize() { return size; } diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java index c0426ddda2c005e7b53a8b85a83e02f70ea73a0e..5518806dc02d8b92568f73e7c9e5677e90525d20 100644 --- a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java +++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java @@ -846,10 +846,10 @@ public class AnalyzerTest { Frame[] frames = analyzer.analyze("C", this); int actualMaxStack = 0; int actualMaxLocals = 0; - for (int i = 0; i < frames.length; ++i) { - if (frames[i] != null) { - actualMaxStack = Math.max(actualMaxStack, frames[i].getStackSize()); - actualMaxLocals = Math.max(actualMaxLocals, frames[i].getLocals()); + for (Frame frame : frames) { + if (frame != null) { + actualMaxStack = Math.max(actualMaxStack, frame.getStackSize()); + actualMaxLocals = Math.max(actualMaxLocals, frame.getLocals()); } } assertEquals(maxStack, actualMaxStack, "maxStack"); diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/BasicInterpreterTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/BasicInterpreterTest.java index efb0f6eff552e5662ec7a276642c42213f145cbb..204bad970171d44aa46a8dc6e6eaae4201c078a1 100644 --- a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/BasicInterpreterTest.java +++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/BasicInterpreterTest.java @@ -33,8 +33,9 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.io.FileInputStream; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -67,7 +68,7 @@ public class BasicInterpreterTest extends AsmTest { public void testMergeWithJsrReachableFromTwoDifferentPaths() throws IOException, AnalyzerException { ClassReader classReader = - new ClassReader(new FileInputStream("src/test/resources/Issue316204.class")); + new ClassReader(Files.newInputStream(Paths.get("src/test/resources/Issue316204.class"))); ClassNode classNode = new ClassNode(); classReader.accept(classNode, 0); Analyzer analyzer = new Analyzer<>(new BasicInterpreter()); diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java index 3e321f04971b4fbe08feb7bc2f41269b486a5f9a..5c06d3a00509d7efda1c42ab8dfe3e1a83976cc7 100644 --- a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java +++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java @@ -71,9 +71,9 @@ public class SimpleVerifierTest extends AsmTest implements Opcodes { methodNode.visitMaxs(10, 10); anaylzer.analyze("C", methodNode); Frame[] frames = anaylzer.getFrames(); - for (int i = 0; i < frames.length; ++i) { - if (frames[i] != null) { - frames[i].toString(); + for (Frame frame : frames) { + if (frame != null) { + frame.toString(); } } anaylzer.getHandlers(0); diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/ValueTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/ValueTest.java index d59619da5914162b07c4d1921ea45945cc049416..e1c22a028bba00d8af18893676284a5f076544dd 100644 --- a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/ValueTest.java +++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/ValueTest.java @@ -46,10 +46,10 @@ public class ValueTest { @Test public void testBasicValue() { - assertTrue(BasicValue.UNINITIALIZED_VALUE.equals(new BasicValue(null))); - assertTrue(BasicValue.INT_VALUE.equals(new BasicValue(Type.INT_TYPE))); - assertTrue(BasicValue.INT_VALUE.equals(BasicValue.INT_VALUE)); - assertFalse(BasicValue.INT_VALUE.equals(new Object())); + assertEquals(new BasicValue(null), BasicValue.UNINITIALIZED_VALUE); + assertEquals(new BasicValue(Type.INT_TYPE), BasicValue.INT_VALUE); + assertEquals(BasicValue.INT_VALUE, BasicValue.INT_VALUE); + assertNotEquals(new Object(), BasicValue.INT_VALUE); assertTrue(BasicValue.REFERENCE_VALUE.isReference()); assertTrue(new BasicValue(Type.getObjectType("[I")).isReference()); @@ -69,10 +69,10 @@ public class ValueTest { public void testSourceValue() { assertEquals(2, new SourceValue(2).getSize()); - assertTrue(new SourceValue(1).equals(new SourceValue(1))); - assertFalse(new SourceValue(1).equals(new SourceValue(1, new InsnNode(Opcodes.NOP)))); - assertFalse(new SourceValue(1).equals(new SourceValue(2))); - assertFalse(new SourceValue(1).equals(null)); + assertEquals(new SourceValue(1), new SourceValue(1)); + assertNotEquals(new SourceValue(1), new SourceValue(1, new InsnNode(Opcodes.NOP))); + assertNotEquals(new SourceValue(1), new SourceValue(2)); + assertNotEquals(new SourceValue(1), null); assertEquals(0, new SourceValue(1).hashCode()); assertNotEquals(0, new SourceValue(1, new InsnNode(Opcodes.NOP)).hashCode()); diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java index f9abc924722a8ee91c8625857e32288c34d40053..95b4621f445d61505d57e87a61f6d2b5afdcd67f 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java @@ -554,8 +554,8 @@ public class AnalyzerAdapter extends MethodVisitor { if (firstDescriptorChar == '(') { int numSlots = 0; Type[] types = Type.getArgumentTypes(descriptor); - for (int i = 0; i < types.length; ++i) { - numSlots += types[i].getSize(); + for (Type type : types) { + numSlots += type.getSize(); } pop(numSlots); } else if (firstDescriptorChar == 'J' || firstDescriptorChar == 'D') { diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java index c9ca50107ea3299811f8af743ce95897ef1a1b7f..971c7a7f3454f5218bfa72f5bdda6c7c9950b774 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java @@ -425,6 +425,7 @@ public class GeneratorAdapter extends LocalVariablesSorter { break; default: mv.visitLdcInsn(value); + break; } } } @@ -915,6 +916,7 @@ public class GeneratorAdapter extends LocalVariablesSorter { break; default: unboxMethod = null; + break; } if (unboxMethod == null) { checkCast(type); diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/Method.java b/asm-commons/src/main/java/org/objectweb/asm/commons/Method.java index e2ef1bc82fcc3bbf74ba2a94b2487f2b5d80e63b..94c53bdfdcd925c609d8afd9e7d0b03dacacad83 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/Method.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/Method.java @@ -162,8 +162,7 @@ public class Method { } stringBuilder.append(argumentDescriptor); } while (currentArgumentEndIndex != -1); - stringBuilder.append(')'); - stringBuilder.append(getDescriptorInternal(returnType, defaultPackage)); + stringBuilder.append(')').append(getDescriptorInternal(returnType, defaultPackage)); return new Method(methodName, stringBuilder.toString()); } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java b/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java index f0efd6d90e6b6c26e5e3504dfca948ec948216ae..6bb512626d3b4852fa69dd56a99fa00c9db1c050 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java @@ -451,8 +451,7 @@ public class SerialVersionUIDAdder extends ClassVisitor { final DataOutput dataOutputStream, final boolean dotted) throws IOException { - int size = itemCollection.size(); - Item[] items = itemCollection.toArray(new Item[size]); + Item[] items = itemCollection.toArray(new Item[0]); Arrays.sort( items, new Comparator() { diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java index 895c9336ca3a46e1d410e39a0b5ab4addc4b5289..e245d2f6739e1a6a47c982986ae04c9e63ec754b 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java @@ -95,6 +95,7 @@ public class TryCatchBlockSorter extends MethodNode { tryCatchBlocks, new Comparator() { + @Override public int compare( final TryCatchBlockNode tryCatchBlockNode1, final TryCatchBlockNode tryCatchBlockNode2) { diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java index d024d340d4109d818f7d24c28594174e6fdd1c8e..16bc864dda5beedd893f6cc7766e9a3a40a12efe 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java @@ -417,6 +417,16 @@ public class AdviceAdapterTest extends AsmTest { classWriter.visitField(Opcodes.ACC_STATIC, "f", "[[I", null, null); + MethodVisitor defaultConstructorVisitor = + classWriter.visitMethod(Opcodes.ACC_PUBLIC, "", "()V", null, null); + defaultConstructorVisitor.visitCode(); + defaultConstructorVisitor.visitVarInsn(Opcodes.ALOAD, 0); + defaultConstructorVisitor.visitMethodInsn( + Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V", false); + defaultConstructorVisitor.visitInsn(Opcodes.RETURN); + defaultConstructorVisitor.visitMaxs(0, 0); + defaultConstructorVisitor.visitEnd(); + String descriptor = "(I)V"; MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "", descriptor, null, null); diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java index 2d4128fef1a7fdf87b98db0852dbb78eaa5b4c31..2b8d9732661227581699df9b746c20a62bd5e212 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java @@ -32,6 +32,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.objectweb.asm.test.Assertions.assertThat; import java.util.Arrays; +import java.util.Locale; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -211,6 +212,8 @@ public class ClassRemapperTest extends AsmTest { static class UpperCaseRemapper extends Remapper { + private static final Locale LOCALE = Locale.ENGLISH; + private final String internalClassName; private final String remappedInternalClassName; @@ -219,7 +222,7 @@ public class ClassRemapperTest extends AsmTest { this.remappedInternalClassName = internalClassName.equals("module-info") ? internalClassName - : internalClassName.toUpperCase(); + : internalClassName.toUpperCase(LOCALE); } String getRemappedClassName() { @@ -245,17 +248,17 @@ public class ClassRemapperTest extends AsmTest { if (name.equals("") || name.equals("")) { return name; } - return owner.equals(internalClassName) ? name.toUpperCase() : name; + return owner.equals(internalClassName) ? name.toUpperCase(LOCALE) : name; } @Override public String mapInvokeDynamicMethodName(final String name, final String descriptor) { - return name.toUpperCase(); + return name.toUpperCase(LOCALE); } @Override public String mapFieldName(final String owner, final String name, final String descriptor) { - return owner.equals(internalClassName) ? name.toUpperCase() : name; + return owner.equals(internalClassName) ? name.toUpperCase(LOCALE) : name; } @Override diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java index 7916d1a0d39ce00a563d8eaac0ff9c31a5396641..c38c72aea836fde93eb8bf157ad76dc0297339db 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java @@ -31,9 +31,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.objectweb.asm.test.Assertions.assertThat; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -137,7 +138,7 @@ public class LocalVariablesSorterTest extends AsmTest { @Test public void testSortLocalVariablesAndInstantiate() throws FileNotFoundException, IOException { ClassReader classReader = - new ClassReader(new FileInputStream("src/test/resources/Issue317586.class")); + new ClassReader(Files.newInputStream(Paths.get("src/test/resources/Issue317586.class"))); ClassWriter classWriter = new ClassWriter(0); ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM7, classWriter) { diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/MethodTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/MethodTest.java index 3a5412b21cfd57c3b246f5f705c55f17e4e62204..60cf151770b0ef75664b48218af89baa224197d7 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/MethodTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/MethodTest.java @@ -29,9 +29,8 @@ package org.objectweb.asm.commons; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import org.objectweb.asm.Type; @@ -102,14 +101,14 @@ public class MethodTest { @Test public void testEquals() { - assertFalse(new Method("name", "()V").equals(null)); - assertFalse(new Method("name", "()V").equals(new Method("other", "()V"))); - assertFalse(new Method("name", "()V").equals(new Method("name", "(I)J"))); - assertTrue(new Method("name", "()V").equals(Method.getMethod("void name()"))); + assertNotEquals(new Method("name", "()V"), null); + assertNotEquals(new Method("name", "()V"), new Method("other", "()V")); + assertNotEquals(new Method("name", "()V"), new Method("name", "(I)J")); + assertEquals(new Method("name", "()V"), Method.getMethod("void name()")); } @Test public void testHashCode() { - assertTrue(new Method("name", "()V").hashCode() != 0); + assertNotEquals(0, new Method("name", "()V").hashCode()); } } diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionAnonymousInnerClass.java b/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionAnonymousInnerClass.java index aa7fdfc8890ea951c37f240ac04978a942d318e5..cbf2a0ed06a4128cd1598b7fe9ddb5ae72a5888c 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionAnonymousInnerClass.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionAnonymousInnerClass.java @@ -34,7 +34,9 @@ import java.io.Serializable; * * @author Eric Bruneton */ -class SerialVersionAnonymousInnerClass implements Serializable { +class SerialVersionAnonymousInnerClass implements Serializable { // NOPMD(MissingSerialVersionUID) + + // No serial version UID on purpose, to test SerialVersionUIDAdder. public static final SerialVersionAnonymousInnerClass anonymousInnerClass = new SerialVersionAnonymousInnerClass() {}; diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionClass.java b/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionClass.java index 3859654f9b4a75103afe29af244e5414aeefe478..20e315719c18ede6bae250e82aac4de23feaac77 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionClass.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionClass.java @@ -34,11 +34,14 @@ import java.io.Serializable; * * @author Eric Bruneton */ -class SerialVersionClass implements Serializable { +class SerialVersionClass implements Serializable { // NOPMD(MissingSerialVersionUID) + + // No serial version UID on purpose, to test SerialVersionUIDAdder. protected static final int someField = 32; static { + assert someField > 0; } SerialVersionClass() {} diff --git a/asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java b/asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java index 935fb1c604ecfa47f97b5eaa51f5ca9c77230073..7a7caaa3cf70b9ba8a2990550997f7cef24f41d1 100644 --- a/asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java +++ b/asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java @@ -374,7 +374,7 @@ public abstract class AsmTest { arguments.add(Array.get(Array.newInstance(parameterType, 1), 0)); } constructor.setAccessible(true); - constructor.newInstance(arguments.toArray(new Object[arguments.size()])); + constructor.newInstance(arguments.toArray(new Object[0])); } } catch (ClassNotFoundException e) { // Should never happen given the ByteClassLoader implementation. @@ -386,7 +386,8 @@ public abstract class AsmTest { fail("Can't instantiate class " + className, e); } catch (InvocationTargetException e) { // If an exception occurs in the invoked constructor, it means the class was successfully - // verified first. + // verified first. Still, we fail the test to be on the safe side. + fail("An exception occurred in the constructor of " + className, e); } return byteClassLoader.classLoaded(); } diff --git a/asm-test/src/main/java/org/objectweb/asm/test/ClassDump.java b/asm-test/src/main/java/org/objectweb/asm/test/ClassDump.java index c11d92a625f31a9687d853971a8dfd2923fe06e6..1b8402681677a2dbb06e1df2ac78c2c6562e5bfc 100644 --- a/asm-test/src/main/java/org/objectweb/asm/test/ClassDump.java +++ b/asm-test/src/main/java/org/objectweb/asm/test/ClassDump.java @@ -300,10 +300,6 @@ class ClassDump { dumpConstantValueAttribute(parser, builder); } else if (attributeName.equals("Code")) { dumpCodeAttribute(parser, builder); - } else if (attributeName.equals("CodeComment")) { - // empty non-standard attribute used for tests. - } else if (attributeName.equals("Comment")) { - // empty non-standard attribute used for tests. } else if (attributeName.equals("StackMapTable")) { dumpStackMapTableAttribute(parser, builder); } else if (attributeName.equals("Exceptions")) { @@ -358,7 +354,8 @@ class ClassDump { dumpNestMembersAttribute(parser, builder); } else if (attributeName.equals("StackMap")) { dumpStackMapAttribute(parser, builder); - } else { + } else if (!attributeName.equals("CodeComment") && !attributeName.equals("Comment")) { + // Not a standard attribute nor one the of empty non-standard attributes used for tests. throw new IOException("Unknown attribute " + attributeName); } } @@ -1039,8 +1036,8 @@ class ClassDump { final int attributeLength, final Parser parser, final Builder builder) throws IOException { byte[] attributeData = parser.bytes(attributeLength); StringBuilder stringBuilder = new StringBuilder(); - for (int i = 0; i < attributeData.length; ++i) { - stringBuilder.append(attributeData[i]).append(','); + for (byte data : attributeData) { + stringBuilder.append(data).append(','); } builder.add("debug_extension: ", stringBuilder.toString()); } @@ -2385,6 +2382,7 @@ class ClassDump { name = stringBuilder.toString(); } + @Override public int compareTo(final Builder builder) { return name.compareTo(builder.name); } diff --git a/asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java b/asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java index d92606d7be356c59e5c5fd79c539262703dfc50d..3d64659278f77e81adbb83c6c90e3f8844f805e0 100644 --- a/asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java +++ b/asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java @@ -65,6 +65,7 @@ public class AsmTestTest extends AsmTest { break; default: fail("Unknown API value"); + break; } } @@ -133,6 +134,7 @@ public class AsmTestTest extends AsmTest { break; default: fail("Unknown invalid class"); + break; } } } diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/InsnList.java b/asm-tree/src/main/java/org/objectweb/asm/tree/InsnList.java index 7ab41b5cc35922867d58d11eb2f1538b0f0a0eea..4c96726b68c806d762bcf7cbd6b9a1e1b4181b24 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/InsnList.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/InsnList.java @@ -496,10 +496,12 @@ public class InsnList { } } + @Override public boolean hasNext() { return nextInsn != null; } + @Override public Object next() { if (nextInsn == null) { throw new NoSuchElementException(); @@ -511,6 +513,7 @@ public class InsnList { return result; } + @Override public void remove() { if (remove != null) { if (remove == nextInsn) { @@ -525,10 +528,12 @@ public class InsnList { } } + @Override public boolean hasPrevious() { return previousInsn != null; } + @Override public Object previous() { AbstractInsnNode result = previousInsn; nextInsn = result; @@ -537,6 +542,7 @@ public class InsnList { return result; } + @Override public int nextIndex() { if (nextInsn == null) { return size(); @@ -547,6 +553,7 @@ public class InsnList { return nextInsn.index; } + @Override public int previousIndex() { if (previousInsn == null) { return -1; @@ -557,6 +564,7 @@ public class InsnList { return previousInsn.index; } + @Override public void add(final Object o) { if (nextInsn != null) { InsnList.this.insertBefore(nextInsn, (AbstractInsnNode) o); @@ -569,6 +577,7 @@ public class InsnList { remove = null; } + @Override public void set(final Object o) { if (remove != null) { InsnList.this.set(remove, (AbstractInsnNode) o); diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleExportNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleExportNode.java index eb2c35fcd80ad0ba133ff05177c609bf5a8e31a0..6abb96e8f311cc4ae2a07cd4b4cd261afe324d93 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleExportNode.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleExportNode.java @@ -74,6 +74,6 @@ public class ModuleExportNode { */ public void accept(final ModuleVisitor moduleVisitor) { moduleVisitor.visitExport( - packaze, access, modules == null ? null : modules.toArray(new String[modules.size()])); + packaze, access, modules == null ? null : modules.toArray(new String[0])); } } diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleOpenNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleOpenNode.java index 2339df1009a95571578c3bb507927c1c6c034c55..bcbb64806457acadc14d9094be7cf49f24400c09 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleOpenNode.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleOpenNode.java @@ -74,6 +74,6 @@ public class ModuleOpenNode { */ public void accept(final ModuleVisitor moduleVisitor) { moduleVisitor.visitOpen( - packaze, access, modules == null ? null : modules.toArray(new String[modules.size()])); + packaze, access, modules == null ? null : modules.toArray(new String[0])); } } diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleProvideNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleProvideNode.java index 1a48fad257fbadf3a394e4527956f48805b9990e..601c7fd91ec03bc6a8c1e148c220985e0f7ad528 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleProvideNode.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleProvideNode.java @@ -61,6 +61,6 @@ public class ModuleProvideNode { * @param moduleVisitor a module visitor. */ public void accept(final ModuleVisitor moduleVisitor) { - moduleVisitor.visitProvide(service, providers.toArray(new String[providers.size()])); + moduleVisitor.visitProvide(service, providers.toArray(new String[0])); } } diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/Util.java b/asm-tree/src/main/java/org/objectweb/asm/tree/Util.java index 7a76168219af4527846c0e17953f82a4ab1c856b..df9171cbb920a1fda75ce1ac2b3180c098d07d43 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/Util.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/Util.java @@ -150,7 +150,7 @@ final class Util { static List asArrayList(final int length, final T[] array) { List list = new ArrayList(length); for (int i = 0; i < length; ++i) { - list.add(array[i]); + list.add(array[i]); // NOPMD(UseArraysAsList): we convert a part of the array. } return list; } diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java index c216f95acfd19fc5e0b885a388c60c81d37fa702..49ad9ca102e0f34d2e0518ceb6e5440a6d804c61 100644 --- a/asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java +++ b/asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java @@ -28,6 +28,7 @@ package org.objectweb.asm.tree; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -240,12 +241,12 @@ public class ClassNodeTest extends AsmTest implements Opcodes { MethodInsnNode methodInsnNode = new MethodInsnNode(INVOKESTATIC, "owner", "name", "()I"); assertEquals(AbstractInsnNode.METHOD_INSN, methodInsnNode.getType()); assertEquals(INVOKESTATIC, methodInsnNode.getOpcode()); - assertEquals(false, methodInsnNode.itf); + assertFalse(methodInsnNode.itf); methodInsnNode = new MethodInsnNode(INVOKEINTERFACE, "owner", "name", "()I"); assertEquals(AbstractInsnNode.METHOD_INSN, methodInsnNode.getType()); assertEquals(INVOKEINTERFACE, methodInsnNode.getOpcode()); - assertEquals(true, methodInsnNode.itf); + assertTrue(methodInsnNode.itf); } @Test @@ -256,7 +257,7 @@ public class ClassNodeTest extends AsmTest implements Opcodes { assertEquals("owner", methodInsnNode.owner); assertEquals("name", methodInsnNode.name); assertEquals("()I", methodInsnNode.desc); - assertEquals(false, methodInsnNode.itf); + assertFalse(methodInsnNode.itf); methodInsnNode.setOpcode(INVOKESPECIAL); assertEquals(INVOKESPECIAL, methodInsnNode.getOpcode()); diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java index c84cbcd2e1336db2330ef82771bcc8ff8c5945fe..195002e707d4c5f9accb9a94c7a9791699d1d151 100644 --- a/asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java +++ b/asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java @@ -100,7 +100,7 @@ public class InsnListTest { @Test public void testContains() { - assertEquals(false, list1.contains(new InsnNode(0))); + assertFalse(list1.contains(new InsnNode(0))); } @Test @@ -347,7 +347,7 @@ public class InsnListTest { assertEquals(insn, list1.getFirst()); assertEquals(insn, list1.getLast()); assertEquals(insn, list1.get(0)); - assertEquals(true, list1.contains(insn)); + assertTrue(list1.contains(insn)); assertEquals(0, list1.indexOf(insn)); assertEqualInsnArrays(new AbstractInsnNode[] {insn}, list1.toArray()); assertEquals(null, insn.getPrevious()); @@ -363,7 +363,7 @@ public class InsnListTest { assertEquals(insn, list1.getLast()); assertEquals(1, list1.indexOf(insn)); assertEquals(insn, list1.get(1)); - assertEquals(true, list1.contains(insn)); + assertTrue(list1.contains(insn)); } @Test @@ -395,8 +395,8 @@ public class InsnListTest { assertEquals(insn1, list1.getFirst()); assertEquals(insn2, list1.getLast()); assertEquals(insn1, list1.get(0)); - assertEquals(true, list1.contains(insn1)); - assertEquals(true, list1.contains(insn2)); + assertTrue(list1.contains(insn1)); + assertTrue(list1.contains(insn2)); assertEquals(0, list1.indexOf(insn1)); assertEquals(1, list1.indexOf(insn2)); assertEqualInsnArrays(new AbstractInsnNode[] {insn1, insn2}, list1.toArray()); @@ -411,9 +411,9 @@ public class InsnListTest { assertEquals(insn, list1.getFirst()); assertEquals(insn2, list1.getLast()); assertEquals(insn, list1.get(0)); - assertEquals(true, list1.contains(insn)); - assertEquals(true, list1.contains(insn1)); - assertEquals(true, list1.contains(insn2)); + assertTrue(list1.contains(insn)); + assertTrue(list1.contains(insn1)); + assertTrue(list1.contains(insn2)); assertEquals(0, list1.indexOf(insn)); assertEquals(1, list1.indexOf(insn1)); assertEquals(2, list1.indexOf(insn2)); @@ -433,7 +433,7 @@ public class InsnListTest { assertEquals(insn, list1.getFirst()); assertEquals(insn, list1.getLast()); assertEquals(insn, list1.get(0)); - assertEquals(true, list1.contains(insn)); + assertTrue(list1.contains(insn)); assertEquals(0, list1.indexOf(insn)); assertEqualInsnArrays(new AbstractInsnNode[] {insn}, list1.toArray()); } @@ -446,7 +446,7 @@ public class InsnListTest { assertEquals(2, list1.size()); assertEquals(insn, list1.getFirst()); assertEquals(insn, list1.get(0)); - assertEquals(true, list1.contains(insn)); + assertTrue(list1.contains(insn)); assertEquals(0, list1.indexOf(insn)); } @@ -471,8 +471,8 @@ public class InsnListTest { assertEquals(insn1, list1.getFirst()); assertEquals(insn2, list1.getLast()); assertEquals(insn1, list1.get(0)); - assertEquals(true, list1.contains(insn1)); - assertEquals(true, list1.contains(insn2)); + assertTrue(list1.contains(insn1)); + assertTrue(list1.contains(insn2)); assertEquals(0, list1.indexOf(insn1)); assertEquals(1, list1.indexOf(insn2)); assertEqualInsnArrays(new AbstractInsnNode[] {insn1, insn2}, list1.toArray()); @@ -487,9 +487,9 @@ public class InsnListTest { assertEquals(insn1, list1.getFirst()); assertEquals(insn, list1.getLast()); assertEquals(insn1, list1.get(0)); - assertEquals(true, list1.contains(insn)); - assertEquals(true, list1.contains(insn1)); - assertEquals(true, list1.contains(insn2)); + assertTrue(list1.contains(insn)); + assertTrue(list1.contains(insn1)); + assertTrue(list1.contains(insn2)); assertEquals(0, list1.indexOf(insn1)); assertEquals(1, list1.indexOf(insn2)); assertEquals(2, list1.indexOf(insn)); @@ -510,7 +510,7 @@ public class InsnListTest { assertEquals(insn1, list2.getFirst()); assertEquals(insn2, list2.getLast()); assertEquals(insn1, list2.get(0)); - assertEquals(true, list2.contains(insn)); + assertTrue(list2.contains(insn)); assertEquals(1, list2.indexOf(insn)); assertEqualInsnArrays(new AbstractInsnNode[] {insn1, insn, insn2}, list2.toArray()); } @@ -523,7 +523,7 @@ public class InsnListTest { assertEquals(insn1, list2.getFirst()); assertEquals(insn, list2.getLast()); assertEquals(insn1, list2.get(0)); - assertEquals(true, list2.contains(insn)); + assertTrue(list2.contains(insn)); assertEquals(2, list2.indexOf(insn)); assertEqualInsnArrays(new AbstractInsnNode[] {insn1, insn2, insn}, list2.toArray()); } @@ -536,7 +536,7 @@ public class InsnListTest { assertEquals(insn1, list2.getFirst()); assertEquals(insn2, list2.getLast()); assertEquals(insn, list2.get(1)); - assertEquals(true, list2.contains(insn)); + assertTrue(list2.contains(insn)); assertEquals(1, list2.indexOf(insn)); assertEqualInsnArrays(new AbstractInsnNode[] {insn1, insn, insn2}, list2.toArray()); } @@ -549,7 +549,7 @@ public class InsnListTest { assertEquals(insn, list2.getFirst()); assertEquals(insn2, list2.getLast()); assertEquals(insn, list2.get(0)); - assertEquals(true, list2.contains(insn)); + assertTrue(list2.contains(insn)); assertEquals(0, list2.indexOf(insn)); assertEqualInsnArrays(new AbstractInsnNode[] {insn, insn1, insn2}, list2.toArray()); } @@ -586,9 +586,9 @@ public class InsnListTest { assertEquals(4, list1.size()); assertEquals(insn, list1.getFirst()); assertEquals(insn, list1.get(0)); - assertEquals(true, list1.contains(insn)); - assertEquals(true, list1.contains(insn1)); - assertEquals(true, list1.contains(insn2)); + assertTrue(list1.contains(insn)); + assertTrue(list1.contains(insn1)); + assertTrue(list1.contains(insn2)); assertEquals(0, list1.indexOf(insn)); assertEquals(1, list1.indexOf(insn1)); assertEquals(2, list1.indexOf(insn2)); @@ -603,9 +603,9 @@ public class InsnListTest { assertEquals(insn, list1.getFirst()); assertEquals(insn2, list1.getLast()); assertEquals(insn, list1.get(0)); - assertEquals(true, list1.contains(insn)); - assertEquals(true, list1.contains(insn1)); - assertEquals(true, list1.contains(insn2)); + assertTrue(list1.contains(insn)); + assertTrue(list1.contains(insn1)); + assertTrue(list1.contains(insn2)); assertEquals(0, list1.indexOf(insn)); assertEquals(1, list1.indexOf(insn1)); assertEquals(2, list1.indexOf(insn2)); @@ -638,9 +638,9 @@ public class InsnListTest { assertEquals(4, list1.size()); assertEquals(insn1, list1.get(1)); assertEquals(insn2, list1.get(2)); - assertEquals(true, list1.contains(insn)); - assertEquals(true, list1.contains(insn1)); - assertEquals(true, list1.contains(insn2)); + assertTrue(list1.contains(insn)); + assertTrue(list1.contains(insn1)); + assertTrue(list1.contains(insn2)); assertEquals(3, list1.indexOf(insn)); assertEquals(1, list1.indexOf(insn1)); assertEquals(2, list1.indexOf(insn2)); @@ -655,9 +655,9 @@ public class InsnListTest { assertEquals(insn1, list1.getFirst()); assertEquals(insn, list1.getLast()); assertEquals(insn1, list1.get(0)); - assertEquals(true, list1.contains(insn)); - assertEquals(true, list1.contains(insn1)); - assertEquals(true, list1.contains(insn2)); + assertTrue(list1.contains(insn)); + assertTrue(list1.contains(insn1)); + assertTrue(list1.contains(insn2)); assertEquals(2, list1.indexOf(insn)); assertEquals(0, list1.indexOf(insn1)); assertEquals(1, list1.indexOf(insn2)); @@ -677,7 +677,7 @@ public class InsnListTest { assertEquals(0, list1.size()); assertEquals(null, list1.getFirst()); assertEquals(null, list1.getLast()); - assertEquals(false, list1.contains(insn)); + assertFalse(list1.contains(insn)); assertEqualInsnArrays(new AbstractInsnNode[0], list1.toArray()); assertEquals(null, insn.getPrevious()); assertEquals(null, insn.getNext()); @@ -689,7 +689,7 @@ public class InsnListTest { list1.add(insn); list1.add(new InsnNode(0)); list1.remove(insn); - assertEquals(false, list1.contains(insn)); + assertFalse(list1.contains(insn)); assertEquals(null, insn.getPrevious()); assertEquals(null, insn.getNext()); } @@ -701,7 +701,7 @@ public class InsnListTest { list1.add(insn); list1.add(new InsnNode(0)); list1.remove(insn); - assertEquals(false, list1.contains(insn)); + assertFalse(list1.contains(insn)); assertEquals(null, insn.getPrevious()); assertEquals(null, insn.getNext()); } @@ -712,7 +712,7 @@ public class InsnListTest { list1.add(new InsnNode(0)); list1.add(insn); list1.remove(insn); - assertEquals(false, list1.contains(insn)); + assertFalse(list1.contains(insn)); assertEquals(null, insn.getPrevious()); assertEquals(null, insn.getNext()); } @@ -727,7 +727,7 @@ public class InsnListTest { assertEquals(0, list1.size()); assertEquals(null, list1.getFirst()); assertEquals(null, list1.getLast()); - assertEquals(false, list1.contains(insn)); + assertFalse(list1.contains(insn)); assertEqualInsnArrays(new AbstractInsnNode[0], list1.toArray()); assertEquals(null, insn.getPrevious()); assertEquals(null, insn.getNext()); diff --git a/asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java b/asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java index e5ea91b9b6ee0b01bcebf982d2cb87f75e02ef06..49a3bc24d50d688e8e9c103a413249ae9aafd660 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java @@ -897,8 +897,8 @@ public class ASMifier extends Printer { public void visitTableSwitchInsn( final int min, final int max, final Label dflt, final Label... labels) { stringBuilder.setLength(0); - for (int i = 0; i < labels.length; ++i) { - declareLabel(labels[i]); + for (Label label : labels) { + declareLabel(label); } declareLabel(dflt); @@ -922,8 +922,8 @@ public class ASMifier extends Printer { @Override public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { stringBuilder.setLength(0); - for (int i = 0; i < labels.length; ++i) { - declareLabel(labels[i]); + for (Label label : labels) { + declareLabel(label); } declareLabel(dflt); diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java index 9cebaccfd01b839a7e000aa05b55ea84402816dc..3f4791cf24faba1b18ecc24b1ff7931846642b7c 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java @@ -29,6 +29,7 @@ package org.objectweb.asm.util; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; @@ -542,7 +543,7 @@ public class CheckClassAdapter extends ClassVisitor { CheckMethodAdapter.checkIdentifier(version, name, startIndex, name.length(), null); } catch (IllegalArgumentException e) { throw new IllegalArgumentException( - "Invalid " + source + " (must be a fully qualified name): " + name); + "Invalid " + source + " (must be a fully qualified name): " + name, e); } } @@ -948,7 +949,7 @@ public class CheckClassAdapter extends ClassVisitor { */ public static void main(final String[] args) throws IOException { if (args.length != 1) { - System.err.println( + System.err.println( // NOPMD(SystemPrintln): main method. "Verifies the given class.\n" + "Usage: CheckClassAdapter "); return; @@ -956,7 +957,9 @@ public class CheckClassAdapter extends ClassVisitor { ClassReader classReader; if (args[0].endsWith(".class")) { - classReader = new ClassReader(new FileInputStream(args[0])); + InputStream inputStream = + new FileInputStream(args[0]); // NOPMD(AvoidFileStream): can't fix for 1.5 compatibility + classReader = new ClassReader(inputStream); } else { classReader = new ClassReader(args[0]); } diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java index 0d93eb3044d494e0d527fafc41fda08a2aaedfcc..824c68046dc9083214f718559266235efc81e155 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java @@ -450,7 +450,8 @@ public class CheckMethodAdapter extends MethodVisitor { } catch (IndexOutOfBoundsException e) { if (maxLocals == 0 && maxStack == 0) { throw new IllegalArgumentException( - "Data flow checking option requires valid, non zero maxLocals and maxStack."); + "Data flow checking option requires valid, non zero maxLocals and maxStack.", + e); } throwError(analyzer, e); } catch (AnalyzerException e) { @@ -847,8 +848,8 @@ public class CheckMethodAdapter extends MethodVisitor { checkLabel(labels[i], false, "label at index " + i); } super.visitTableSwitchInsn(min, max, dflt, labels); - for (int i = 0; i < labels.length; ++i) { - referencedLabels.add(labels[i]); + for (Label label : labels) { + referencedLabels.add(label); } ++insnCount; } @@ -866,8 +867,8 @@ public class CheckMethodAdapter extends MethodVisitor { } super.visitLookupSwitchInsn(dflt, keys, labels); referencedLabels.add(dflt); - for (int i = 0; i < labels.length; ++i) { - referencedLabels.add(labels[i]); + for (Label label : labels) { + referencedLabels.add(label); } ++insnCount; } @@ -1343,7 +1344,7 @@ public class CheckMethodAdapter extends MethodVisitor { CheckMethodAdapter.checkIdentifier(version, name, startIndex, name.length(), null); } catch (IllegalArgumentException e) { throw new IllegalArgumentException( - INVALID + message + " (must be an internal class name): " + name); + INVALID + message + " (must be an internal class name): " + name, e); } } @@ -1408,8 +1409,8 @@ public class CheckMethodAdapter extends MethodVisitor { } try { checkInternalClassName(version, descriptor.substring(startPos + 1, endPos), null); - } catch (IllegalArgumentException unused) { - throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor, e); } return endPos + 1; default: diff --git a/asm-util/src/main/java/org/objectweb/asm/util/Printer.java b/asm-util/src/main/java/org/objectweb/asm/util/Printer.java index 51534e28520c53a7a84fc72c7c5e661816feda43..b2b171ff94f0f24b03323bd2b5c6c10532108021 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/Printer.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/Printer.java @@ -29,6 +29,7 @@ package org.objectweb.asm.util; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -1224,7 +1225,7 @@ public abstract class Printer { static void main(final String usage, final Printer printer, final String[] args) throws IOException { if (args.length < 1 || args.length > 2 || (args[0].equals("-debug") && args.length != 2)) { - System.err.println(usage); + System.err.println(usage); // NOPMD(SystemPrintln): main method. return; } @@ -1244,7 +1245,9 @@ public abstract class Printer { if (className.endsWith(".class") || className.indexOf('\\') != -1 || className.indexOf('/') != -1) { - new ClassReader(new FileInputStream(className)).accept(traceClassVisitor, parsingOptions); + InputStream inputStream = + new FileInputStream(className); // NOPMD(AvoidFileStream): can't fix for 1.5 compatibility + new ClassReader(inputStream).accept(traceClassVisitor, parsingOptions); } else { new ClassReader(className).accept(traceClassVisitor, parsingOptions); } diff --git a/asm-util/src/main/java/org/objectweb/asm/util/Textifier.java b/asm-util/src/main/java/org/objectweb/asm/util/Textifier.java index 4e373ca53855748c173e358516fc97d7127829ab..840783250e0538c0419cc178fd2f1e66a3a76712 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/Textifier.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/Textifier.java @@ -398,8 +398,8 @@ public class Textifier extends Printer { appendDescriptor(METHOD_DESCRIPTOR, descriptor); if (exceptions != null && exceptions.length > 0) { stringBuilder.append(" throws "); - for (int i = 0; i < exceptions.length; ++i) { - appendDescriptor(INTERNAL_NAME, exceptions[i]); + for (String exception : exceptions) { + appendDescriptor(INTERNAL_NAME, exception); stringBuilder.append(' '); } } @@ -941,9 +941,8 @@ public class Textifier extends Printer { stringBuilder.append(" none"); } else { stringBuilder.append('\n'); - for (int i = 0; i < bootstrapMethodArguments.length; i++) { + for (Object value : bootstrapMethodArguments) { stringBuilder.append(tab3); - Object value = bootstrapMethodArguments[i]; if (value instanceof String) { Printer.appendString(stringBuilder, (String) value); } else if (value instanceof Type) { @@ -1551,7 +1550,7 @@ public class Textifier extends Printer { } if (frameTypes[i] instanceof String) { String descriptor = (String) frameTypes[i]; - if (descriptor.startsWith("[")) { + if (descriptor.charAt(0) == '[') { appendDescriptor(FIELD_DESCRIPTOR, descriptor); } else { appendDescriptor(INTERNAL_NAME, descriptor); diff --git a/asm-util/src/test/java/org/objectweb/asm/util/ASMifierTest.java b/asm-util/src/test/java/org/objectweb/asm/util/ASMifierTest.java index 9955b67721a4b5dab154e489ae98edbf36b9a99a..9eac67efd28bf54a95d12bd31be165d639ffb24a 100644 --- a/asm-util/src/test/java/org/objectweb/asm/util/ASMifierTest.java +++ b/asm-util/src/test/java/org/objectweb/asm/util/ASMifierTest.java @@ -148,12 +148,12 @@ public class ASMifierTest extends AsmTest { return; } byte[] asmifiedClassFile = compile(classParameter.getName(), asmifiedSource); - String asmifiedClassName = classParameter.getName() + "Dump"; - if (asmifiedClassName.indexOf('.') != -1) { - asmifiedClassName = "asm." + asmifiedClassName; + StringBuilder asmifiedClassName = new StringBuilder(classParameter.getName()).append("Dump"); + if (classParameter.getName().indexOf('.') != -1) { + asmifiedClassName.insert(0, "asm."); } Class asmifiedClass = - new TestClassLoader().defineClass(asmifiedClassName, asmifiedClassFile); + new TestClassLoader().defineClass(asmifiedClassName.toString(), asmifiedClassFile); Method dumpMethod = asmifiedClass.getMethod("dump"); byte[] dumpClassFile = (byte[]) dumpMethod.invoke(null); diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CheckAnnotationAdapterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/CheckAnnotationAdapterTest.java index 9fb52b4c09ccde13a1d392a498c17b2e2ddb53b6..027cf6e033eb13f512265ad6dcb48c73a2099bd0 100644 --- a/asm-util/src/test/java/org/objectweb/asm/util/CheckAnnotationAdapterTest.java +++ b/asm-util/src/test/java/org/objectweb/asm/util/CheckAnnotationAdapterTest.java @@ -45,7 +45,7 @@ public class CheckAnnotationAdapterTest extends AsmTest implements Opcodes { @Test public void testIllegalAnnotationName() { - assertThrows(Exception.class, () -> checkAnnotationAdapter.visit(null, new Integer(0))); + assertThrows(Exception.class, () -> checkAnnotationAdapter.visit(null, Integer.valueOf(0))); } @Test @@ -64,6 +64,6 @@ public class CheckAnnotationAdapterTest extends AsmTest implements Opcodes { @Test public void testIllegalAnnotationValueAfterEnd() { checkAnnotationAdapter.visitEnd(); - assertThrows(Exception.class, () -> checkAnnotationAdapter.visit("name", new Integer(0))); + assertThrows(Exception.class, () -> checkAnnotationAdapter.visit("name", Integer.valueOf(0))); } } diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CheckMethodAdapterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/CheckMethodAdapterTest.java index 93b79ec474a2c8c6aa45f68ec43f10b5798f8f1b..3691a57d2756de886c829fc09414ba6bedfb946e 100644 --- a/asm-util/src/test/java/org/objectweb/asm/util/CheckMethodAdapterTest.java +++ b/asm-util/src/test/java/org/objectweb/asm/util/CheckMethodAdapterTest.java @@ -167,9 +167,11 @@ public class CheckMethodAdapterTest extends AsmTest implements Opcodes { RuntimeException.class, () -> checkMethodAdapter.visitFrame(F_FULL, 1, new Object[] {"LC;"}, 0, null)); checkMethodAdapter.visitInsn(NOP); + Integer invalidFrameValue = + new Integer(0); // NOPMD(IntegerInstantiation): needed to build an invalid value. assertThrows( RuntimeException.class, - () -> checkMethodAdapter.visitFrame(F_FULL, 1, new Object[] {new Integer(0)}, 0, null)); + () -> checkMethodAdapter.visitFrame(F_FULL, 1, new Object[] {invalidFrameValue}, 0, null)); checkMethodAdapter.visitInsn(NOP); assertThrows( RuntimeException.class, diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CodeComment.java b/asm-util/src/test/java/org/objectweb/asm/util/CodeComment.java index 203cf4a90662aa75e63589db4d18d384e6329f65..423d4b68d55648ccc466ca30dae3085f00f61dcb 100644 --- a/asm-util/src/test/java/org/objectweb/asm/util/CodeComment.java +++ b/asm-util/src/test/java/org/objectweb/asm/util/CodeComment.java @@ -77,10 +77,12 @@ public class CodeComment extends Attribute implements ASMifiable, Textifiable { return new ByteVector(); } + @Override public void asmify( final StringBuffer buf, final String varName, final Map labelNames) { buf.append("Attribute ").append(varName).append(" = new org.objectweb.asm.util.CodeComment();"); } + @Override public void textify(final StringBuffer buf, final Map labelNames) {} } diff --git a/asm-util/src/test/java/org/objectweb/asm/util/Comment.java b/asm-util/src/test/java/org/objectweb/asm/util/Comment.java index 06320f84314827a2c16f0fdfc5a3fa426cab0210..f3ab4c6bb5b763845faf3185b0d3c4c19abfc0aa 100644 --- a/asm-util/src/test/java/org/objectweb/asm/util/Comment.java +++ b/asm-util/src/test/java/org/objectweb/asm/util/Comment.java @@ -72,11 +72,13 @@ public class Comment extends Attribute implements ASMifiable, Textifiable { return new ByteVector(); } + @Override public void asmify( final StringBuffer buf, final String varName, final Map labelNames) { buf.append("Attribute ").append(varName).append(" = new org.objectweb.asm.util.Comment();"); } + @Override public void textify(final StringBuffer buf, final Map labelNames) {} @Override diff --git a/asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java index f572a12afd4b1593bed1e06f4552b1219206439f..35dd5744b0edcc20584b483a3a39732dd5a63be7 100644 --- a/asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java +++ b/asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java @@ -105,6 +105,7 @@ public class PrinterTest { public void testBackwardCompatibility() { Printer printer = new StubPrinter(Opcodes.ASM5) { + @Override public void visitMethodInsn( final int opcode, final String owner, @@ -121,6 +122,7 @@ public class PrinterTest { public void testBackwardCompatibilityAsm4() { Printer printer = new StubPrinter(Opcodes.ASM4) { + @Override public void visitMethodInsn( final int opcode, final String owner, final String name, final String descriptor) { // Do nothing. diff --git a/asm/src/main/java/org/objectweb/asm/ClassReader.java b/asm/src/main/java/org/objectweb/asm/ClassReader.java index c0950f2bb50cefa7b3db10ae5a5d7b3cdb965376..47a6b2e4b957dd200b49d7d7cef54a0dc4570154 100644 --- a/asm/src/main/java/org/objectweb/asm/ClassReader.java +++ b/asm/src/main/java/org/objectweb/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/asm/src/main/java/org/objectweb/asm/ClassWriter.java b/asm/src/main/java/org/objectweb/asm/ClassWriter.java index d758c690456cbcc174bc64739ca9bf53a4eb4d3b..8afc979eb83d64e2f7dc6253651d3c7bb23440e2 100644 --- a/asm/src/main/java/org/objectweb/asm/ClassWriter.java +++ b/asm/src/main/java/org/objectweb/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/asm/src/main/java/org/objectweb/asm/MethodWriter.java b/asm/src/main/java/org/objectweb/asm/MethodWriter.java index ccd7e7b34d5d6243cf2c5fa72cb0234093fc559f..50cc2ad71addef3cd17a1fb65fe2c4175d87b0fa 100644 --- a/asm/src/main/java/org/objectweb/asm/MethodWriter.java +++ b/asm/src/main/java/org/objectweb/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/asm/src/main/java/org/objectweb/asm/Type.java b/asm/src/main/java/org/objectweb/asm/Type.java index a0378fdfe099b3c0b372b00cb4c7c3172bbbaa9d..04eab9ff1e9190f5daca539a28252d958dc09faf 100644 --- a/asm/src/main/java/org/objectweb/asm/Type.java +++ b/asm/src/main/java/org/objectweb/asm/Type.java @@ -304,9 +304,8 @@ public final 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 final 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 final 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 final 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 final 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 final 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 final 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 final 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 final 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/asm/src/test/java/org/objectweb/asm/ClassReaderTest.java b/asm/src/test/java/org/objectweb/asm/ClassReaderTest.java index 2b6b4847d62f639451e7d018f8dc96830e8f1ac3..9b1236a0cf791180d5d664e1c8e6e649e9de3f59 100644 --- a/asm/src/test/java/org/objectweb/asm/ClassReaderTest.java +++ b/asm/src/test/java/org/objectweb/asm/ClassReaderTest.java @@ -28,6 +28,7 @@ package org.objectweb.asm; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -108,7 +109,7 @@ public class ClassReaderTest extends AsmTest implements Opcodes { public void testByteArrayConstructorAndAccessors( final PrecompiledClass classParameter, final Api apiParameter) { ClassReader classReader = new ClassReader(classParameter.getBytes()); - assertTrue(classReader.getAccess() != 0); + assertNotEquals(0, classReader.getAccess()); assertEquals(classParameter.getInternalName(), classReader.getClassName()); if (classParameter.getInternalName().equals("module-info")) { assertNull(classReader.getSuperName()); @@ -127,7 +128,7 @@ public class ClassReaderTest extends AsmTest implements Opcodes { byte[] byteBuffer = new byte[classFile.length + 1]; System.arraycopy(classFile, 0, byteBuffer, 1, classFile.length); ClassReader classReader = new ClassReader(byteBuffer, 1, classFile.length); - assertTrue(classReader.getAccess() != 0); + assertNotEquals(0, classReader.getAccess()); assertEquals(classParameter.getInternalName(), classReader.getClassName()); if (classParameter.getInternalName().equals("module-info")) { assertNull(classReader.getSuperName()); @@ -158,7 +159,7 @@ public class ClassReaderTest extends AsmTest implements Opcodes { public void testNameConstructorAndAccessors( final PrecompiledClass classParameter, final Api apiParameter) throws IOException { ClassReader classReader = new ClassReader(classParameter.getName()); - assertTrue(classReader.getAccess() != 0); + assertNotEquals(0, classReader.getAccess()); assertEquals(classParameter.getInternalName(), classReader.getClassName()); if (classParameter.getInternalName().equals("module-info")) { assertNull(classReader.getSuperName()); @@ -179,7 +180,7 @@ public class ClassReaderTest extends AsmTest implements Opcodes { new ClassReader( ClassLoader.getSystemResourceAsStream( classParameter.getName().replace('.', '/') + ".class")); - assertTrue(classReader.getAccess() != 0); + assertNotEquals(0, classReader.getAccess()); assertEquals(classParameter.getInternalName(), classReader.getClassName()); if (classParameter.getInternalName().equals("module-info")) { assertNull(classReader.getSuperName()); @@ -442,7 +443,7 @@ public class ClassReaderTest extends AsmTest implements Opcodes { final String signature, final String superName, final String[] interfaces) { - assertTrue((version & Opcodes.V_PREVIEW) == Opcodes.V_PREVIEW); + assertEquals(Opcodes.V_PREVIEW, version & Opcodes.V_PREVIEW); } }, 0); diff --git a/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java b/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java index 0e89c10f4320b8f1fd45d0538e461fcef5fd25b1..583b9fd7db7dbfb8848d05e658fee3683ba1ee51 100644 --- a/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java +++ b/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java @@ -587,8 +587,7 @@ public class ClassVisitorTest extends AsmTest { return super.visitMethod( access, name, - Type.getMethodDescriptor( - returnType, argumentTypes.toArray(new Type[argumentTypes.size()])), + Type.getMethodDescriptor(returnType, argumentTypes.toArray(new Type[0])), signature, exceptions); } diff --git a/asm/src/test/java/org/objectweb/asm/ClassWriterTest.java b/asm/src/test/java/org/objectweb/asm/ClassWriterTest.java index acb801ab0e67f890e9798e896b08def499d5ecb7..b937770352c1bfe65af1a3ce3877dc81d5e03ca6 100644 --- a/asm/src/test/java/org/objectweb/asm/ClassWriterTest.java +++ b/asm/src/test/java/org/objectweb/asm/ClassWriterTest.java @@ -32,10 +32,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.objectweb.asm.test.Assertions.assertThat; -import java.io.FileInputStream; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Arrays; import java.util.HashSet; import java.util.Random; @@ -104,9 +105,9 @@ public class ClassWriterTest extends AsmTest { @Test public void testNewConst() { ClassWriter classWriter = new ClassWriter(0); - classWriter.newConst(new Byte((byte) 0)); - classWriter.newConst(new Character('0')); - classWriter.newConst(new Short((short) 0)); + classWriter.newConst(Byte.valueOf((byte) 0)); + classWriter.newConst(Character.valueOf('0')); + classWriter.newConst(Short.valueOf((short) 0)); classWriter.newConst(Boolean.FALSE); classWriter.newUTF8("A"); classWriter.newClass("A"); @@ -339,7 +340,7 @@ public class ClassWriterTest extends AsmTest { public void testReadAndWriteWithComputeMaxsAndLargeSubroutines(final String classFileName) throws IOException { ClassReader classReader = - new ClassReader(new FileInputStream("src/test/resources/" + classFileName)); + new ClassReader(Files.newInputStream(Paths.get("src/test/resources/" + classFileName))); ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); classReader.accept(classWriter, attributes(), 0); classWriter.toByteArray(); diff --git a/asm/src/test/java/org/objectweb/asm/ConstantsTest.java b/asm/src/test/java/org/objectweb/asm/ConstantsTest.java index de88e87a92f4faa1c3082ac5aa6f70ad72d6bdc3..5143e2338e2f7d428d6b1a96bb0a3f662e9fe25b 100644 --- a/asm/src/test/java/org/objectweb/asm/ConstantsTest.java +++ b/asm/src/test/java/org/objectweb/asm/ConstantsTest.java @@ -392,6 +392,7 @@ public class ConstantsTest { break; default: fail("Unknown constant " + field.getName()); + break; } } } diff --git a/asm/src/test/java/org/objectweb/asm/HandleTest.java b/asm/src/test/java/org/objectweb/asm/HandleTest.java index 8b661742fe4708bbfb04c11cf980d47150874475..3af4194d659f2494087d2f71f045b8f5982e5436 100644 --- a/asm/src/test/java/org/objectweb/asm/HandleTest.java +++ b/asm/src/test/java/org/objectweb/asm/HandleTest.java @@ -29,6 +29,7 @@ package org.objectweb.asm; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; @@ -62,22 +63,21 @@ public class HandleTest { public void testEquals() { Handle handle1 = new Handle(Opcodes.H_GETFIELD, "owner", "name", "descriptor", false); Handle handle2 = new Handle(Opcodes.H_GETFIELD, "owner", "name", "descriptor", false); - assertTrue(handle1.equals(handle1)); - assertTrue(handle1.equals(handle2)); - assertFalse(handle1.equals(null)); - assertFalse( - handle1.equals(new Handle(Opcodes.H_PUTFIELD, "owner", "name", "descriptor", false))); - assertFalse(handle1.equals(new Handle(Opcodes.H_GETFIELD, "o", "name", "descriptor", false))); - assertFalse(handle1.equals(new Handle(Opcodes.H_GETFIELD, "owner", "n", "descriptor", false))); - assertFalse(handle1.equals(new Handle(Opcodes.H_GETFIELD, "owner", "name", "d", false))); - assertFalse(handle1.equals(new Handle(Opcodes.H_GETFIELD, "owner", "n", "descriptor", true))); + assertEquals(handle1, handle1); + assertEquals(handle1, handle2); + assertNotEquals(handle1, null); + assertNotEquals(handle1, new Handle(Opcodes.H_PUTFIELD, "owner", "name", "descriptor", false)); + assertNotEquals(handle1, new Handle(Opcodes.H_GETFIELD, "o", "name", "descriptor", false)); + assertNotEquals(handle1, new Handle(Opcodes.H_GETFIELD, "owner", "n", "descriptor", false)); + assertNotEquals(handle1, new Handle(Opcodes.H_GETFIELD, "owner", "name", "d", false)); + assertNotEquals(handle1, new Handle(Opcodes.H_GETFIELD, "owner", "n", "descriptor", true)); } @Test public void testHashCode() { - assertTrue( - new Handle(Opcodes.H_INVOKESTATIC, "owner", "name", "descriptor", false).hashCode() != 0); - assertTrue( - new Handle(Opcodes.H_INVOKESTATIC, "owner", "name", "descriptor", true).hashCode() != 0); + assertNotEquals( + 0, new Handle(Opcodes.H_INVOKESTATIC, "owner", "name", "descriptor", false).hashCode()); + assertNotEquals( + 0, new Handle(Opcodes.H_INVOKESTATIC, "owner", "name", "descriptor", true).hashCode()); } } diff --git a/asm/src/test/java/org/objectweb/asm/LabelTest.java b/asm/src/test/java/org/objectweb/asm/LabelTest.java index 9a979fab08b964b5649076b42109e28b70a2fb38..ce4fec6f81570afcda10da7f4184f4415a811e76 100644 --- a/asm/src/test/java/org/objectweb/asm/LabelTest.java +++ b/asm/src/test/java/org/objectweb/asm/LabelTest.java @@ -29,7 +29,6 @@ package org.objectweb.asm; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; @@ -43,7 +42,7 @@ public class LabelTest { /** Tests that {@link Label#toString()} returns strings starting with "L". */ @Test public void testToString() { - assertTrue(new Label().toString().startsWith("L")); + assertEquals('L', new Label().toString().charAt(0)); } /** Tests that {@link Label#getOffset()} returns a correct offset after the label is visited. */ diff --git a/asm/src/test/java/org/objectweb/asm/TypeTest.java b/asm/src/test/java/org/objectweb/asm/TypeTest.java index aa22a7598604290f2412844cfcb64f25fc439436..acb58542ee6934c0523865c1750daf3e321c8580 100644 --- a/asm/src/test/java/org/objectweb/asm/TypeTest.java +++ b/asm/src/test/java/org/objectweb/asm/TypeTest.java @@ -29,9 +29,8 @@ package org.objectweb.asm; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import org.junit.jupiter.api.Test; @@ -366,21 +365,21 @@ public class TypeTest implements Opcodes { @Test public void testEquals() { - assertFalse(Type.getObjectType("I").equals(null)); - assertFalse(Type.getObjectType("I").equals(Type.INT_TYPE)); - assertFalse(Type.getObjectType("I").equals(Type.getObjectType("HI"))); - assertFalse(Type.getObjectType("I").equals(Type.getObjectType("J"))); - assertTrue(Type.getObjectType("I").equals(Type.getType("LI;"))); - assertTrue(Type.getType("LI;").equals(Type.getObjectType("I"))); - assertTrue(Type.INT_TYPE.equals(Type.getType("I"))); + assertNotEquals(Type.getObjectType("I"), null); + assertNotEquals(Type.getObjectType("I"), Type.INT_TYPE); + assertNotEquals(Type.getObjectType("I"), Type.getObjectType("HI")); + assertNotEquals(Type.getObjectType("I"), Type.getObjectType("J")); + assertEquals(Type.getObjectType("I"), Type.getType("LI;")); + assertEquals(Type.getType("LI;"), Type.getObjectType("I")); + assertEquals(Type.INT_TYPE, Type.getType("I")); } @Test public void testHashcode() { - assertTrue(Type.getType("Ljava/lang/Object;").hashCode() != 0); - assertTrue( - Type.getType("Ljava/lang/Object;").hashCode() - == Type.getObjectType("java/lang/Object").hashCode()); - assertTrue(Type.INT_TYPE.hashCode() != Type.getObjectType("I").hashCode()); + assertNotEquals(0, Type.getType("Ljava/lang/Object;").hashCode()); + assertEquals( + Type.getType("Ljava/lang/Object;").hashCode(), + Type.getObjectType("java/lang/Object").hashCode()); + assertNotEquals(Type.INT_TYPE.hashCode(), Type.getObjectType("I").hashCode()); } } diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java index c3bc680f4b5f240c2226f2683ff731fb833185e1..e5869869e028aa289787fc49278d5d1e0de25d51 100644 --- a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java +++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java @@ -29,12 +29,12 @@ package org.objectweb.asm.benchmarks; import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.Files; import java.util.ArrayList; /** @@ -114,7 +114,7 @@ public abstract class AbstractBenchmark { if (file.isDirectory()) { findClasses(file); } else if (file.getName().endsWith(".class")) { - classFiles.add(readInputStream(new FileInputStream(file))); + classFiles.add(readInputStream(Files.newInputStream(file.toPath()))); } } } @@ -130,11 +130,7 @@ public abstract class AbstractBenchmark { outputStream.flush(); return outputStream.toByteArray(); } finally { - try { - inputStream.close(); - } catch (IOException e) { - // Nothing to do. - } + inputStream.close(); } } diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmAdapter.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmAdapter.java index 3b305112606ac43607eab807770984147a21cb02..0937afb2ebd0fb33d9e08f9b3523d53c4d7f8a36 100644 --- a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmAdapter.java +++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmAdapter.java @@ -61,7 +61,7 @@ public class AsmAdapter extends Adapter { } catch (NoSuchFieldException e) { continue; } catch (IllegalAccessException e) { - throw new AssertionError(); + throw new AssertionError(e); } } return ""; diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryProfiler.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryProfiler.java index 9d1b481014570fa265d3245e3697601982cd687f..a4866cae29b6a19b5a9e697a419857348da2f19a 100644 --- a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryProfiler.java +++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryProfiler.java @@ -50,6 +50,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.openjdk.jmh.infra.BenchmarkParams; import org.openjdk.jmh.infra.IterationParams; import org.openjdk.jmh.profile.InternalProfiler; @@ -67,7 +69,7 @@ public class MemoryProfiler implements InternalProfiler { private static final int MAX_WAIT_MSEC = 20 * 1000; - private static Object[] references; + private static Object[] references; // NOPMD(UnusedPrivateField): false positive. private static int referenceCount; private static long usedMemoryBeforeIteration; @@ -130,13 +132,14 @@ public class MemoryProfiler implements InternalProfiler { } } if (gcBeans.isEmpty()) { - System.err.println("WARNING: MXBeans can not report GC info. Cannot get memory used."); + Logger.getLogger(MemoryProfiler.class.getName()) + .log(Level.WARNING, "MXBeans can not report GC info. Cannot get memory used."); return -1; } long startGcCount = countGc(gcBeans); long startTimeMillis = System.currentTimeMillis(); - System.gc(); + System.gc(); // NOPMD(DoNotCallGarbageCollectionExplicitly): needed to measure used memory. while (System.currentTimeMillis() - startTimeMillis < MAX_WAIT_MSEC) { try { Thread.sleep(234); @@ -147,7 +150,8 @@ public class MemoryProfiler implements InternalProfiler { return ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); } } - System.err.println("WARNING: System.gc() was invoked but couldn't detect a GC occurring."); + Logger.getLogger(MemoryProfiler.class.getName()) + .log(Level.WARNING, "WARNING: System.gc() was invoked but couldn't detect a GC occurring."); return -1; } diff --git a/build.gradle b/build.gradle index 6bc554d75d093c0bf64689cecd0b93a56cc10a54..dcc4a8fa8f202a84ecacd204521c3f3d8194fb2a 100644 --- a/build.gradle +++ b/build.gradle @@ -175,6 +175,15 @@ subprojects { checkstyle.maxErrors = 0 checkstyle.maxWarnings = 0 + // Check the code with PMD. + apply plugin: 'pmd' + pmd.toolVersion = '6.5.0' + pmd.ruleSets = [] + pmd.ruleSetFiles = files("${rootDir}/tools/pmd.xml") + // TODO remove these lines when the code is fixed. + pmd.ignoreFailures = true + pmd.consoleOutput = true + compileTestJava { sourceCompatibility = '1.8' targetCompatibility = '1.8' @@ -219,8 +228,9 @@ configure(subprojects.findAll { it.provides }) { compileJava.doLast { def path = project(':tools:retrofitter').sourceSets.main.runtimeClasspath def loader = new URLClassLoader(path.collect {f -> f.toURL()} as URL[]) - def retrofit = loader.loadClass('org.objectweb.asm.tools.Retrofitter') - retrofit.main(sourceSets.main.output.classesDirs.singleFile.toString()) + def retrofitter = + loader.loadClass('org.objectweb.asm.tools.Retrofitter').newInstance() + retrofitter.retrofit sourceSets.main.output.classesDirs.singleFile } } diff --git a/tools/pmd.xml b/tools/pmd.xml new file mode 100644 index 0000000000000000000000000000000000000000..34fde715fa82b243b07393ccf27b11a18e27d8d0 --- /dev/null +++ b/tools/pmd.xml @@ -0,0 +1,102 @@ + + + + PMD rules for ASM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java b/tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java index 039e54b1c7e3cacc1cf865e2b114c5ed53763682..a9cdd595aa9dceb6e5fa0914dbfb1c3c20614694 100644 --- a/tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java +++ b/tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java @@ -29,13 +29,12 @@ package org.objectweb.asm.tools; import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.OutputStream; +import java.nio.file.Files; import java.util.HashMap; import java.util.HashSet; import java.util.zip.GZIPInputStream; @@ -48,41 +47,33 @@ import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; /** - * A command line tool to transform classes in order to make them compatible with Java 1.5, and to - * check that they use only the JDK 1.5 API and JDK 1.5 class file features. The original classes - * can either be transformed "in place", or be copied first to destination directory and transformed - * here (leaving the original classes unchanged). + * A tool to transform classes in order to make them compatible with Java 1.5, and to check that + * they use only the JDK 1.5 API and JDK 1.5 class file features. The original classes can either be + * transformed "in place", or be copied first to destination directory and transformed here (leaving + * the original classes unchanged). * * @author Eric Bruneton * @author Eugene Kuleshov */ -public final class Retrofitter { +public class Retrofitter { /** * The fields and methods of the JDK 1.5 API. Each string has the form * "<owner><name><descriptor>". */ - static final HashSet API = new HashSet(); + private final HashSet jdkApi = new HashSet(); /** * The class hierarchy of the JDK 1.5 API. Maps each class name to the name of its super class. */ - static final HashMap HIERARCHY = new HashMap(); - - private Retrofitter() { - // Empty. - } + private final HashMap jdkHierarchy = new HashMap(); /** - * Transforms the classes from a source directory into a destination directory to make them - * compatible with the JDK 1.5, and checks that they only use the JDK 1.5 API. + * Constructs a new {@link Retrofitter}. * - * @param args First argument: source directory. Optional second argument: destination directory. - * If the second argument is provided classes are copied to this destination directory and - * transformed there. Otherwise they are transformed "in place" in the source directory. - * @throws IOException if a file can't be read or written. + * @throws IOException if the JDK API description file can't be read. */ - public static void main(final String[] args) throws IOException { + public Retrofitter() throws IOException { InputStream inputStream = new GZIPInputStream( Retrofitter.class.getClassLoader().getResourceAsStream("jdk1.5.0.12.txt.gz")); @@ -93,20 +84,25 @@ public final class Retrofitter { if (line.startsWith("class")) { String className = line.substring(6, line.lastIndexOf(' ')); String superClassName = line.substring(line.lastIndexOf(' ') + 1); - HIERARCHY.put(className, superClassName); + jdkHierarchy.put(className, superClassName); } else { - API.add(line); + jdkApi.add(line); } } else { break; } } + } - File src = new File(args[0]); - File dst = args.length > 1 ? new File(args[1]) : null; - if (!retrofit(src, dst)) { - System.exit(1); - } + /** + * Transforms the source class file, or if it is a directory, its files (recursively), in place, + * in order to make them compatible with the JDK 1.5. + * + * @param src source file or directory. + * @throws IOException if the source files can't be read or written. + */ + public void retrofit(final File src) throws IOException { + retrofit(src, null); } /** @@ -116,23 +112,20 @@ public final class Retrofitter { * * @param src source file or directory. * @param dst optional destination file or directory. - * @return true if all the source classes use only the JDK 1.5 API. * @throws IOException if the source or destination file can't be read or written. */ - static boolean retrofit(final File src, final File dst) throws IOException { + public void retrofit(final File src, final File dst) throws IOException { if (src.isDirectory()) { - boolean result = true; File[] files = src.listFiles(); if (files == null) { throw new IOException("Unable to read files of " + src); } for (int i = 0; i < files.length; ++i) { - result &= retrofit(files[i], dst == null ? null : new File(dst, files[i].getName())); + retrofit(files[i], dst == null ? null : new File(dst, files[i].getName())); } - return result; } else if (src.getName().endsWith(".class")) { if (dst == null || !dst.exists() || dst.lastModified() < src.lastModified()) { - ClassReader classReader = new ClassReader(new FileInputStream(src)); + ClassReader classReader = new ClassReader(Files.newInputStream(src.toPath())); ClassWriter classWriter = new ClassWriter(0); ClassVerifier classVerifier = new ClassVerifier(classWriter); ClassRetrofitter classRetrofitter = new ClassRetrofitter(classVerifier); @@ -141,17 +134,13 @@ public final class Retrofitter { if (dst != null && !dst.getParentFile().exists() && !dst.getParentFile().mkdirs()) { throw new IOException("Cannot create directory " + dst.getParentFile()); } - OutputStream os = new FileOutputStream(dst == null ? src : dst); + OutputStream outputStream = Files.newOutputStream((dst == null ? src : dst).toPath()); try { - os.write(classWriter.toByteArray()); + outputStream.write(classWriter.toByteArray()); } finally { - os.close(); + outputStream.close(); } - return classVerifier.ok; } - return true; - } else { - return true; } } @@ -177,7 +166,7 @@ public final class Retrofitter { /** * A ClassVisitor checking that a class uses only JDK 1.5 class file features and the JDK 1.5 API. */ - static class ClassVerifier extends ClassVisitor { + class ClassVerifier extends ClassVisitor { /** The name of the visited class. */ String className; @@ -185,16 +174,12 @@ public final class Retrofitter { /** The name of the currently visited method. */ String currentMethodName; - /** Whether the class uses only JDK 1.5 class file features and APIs. */ - boolean ok; - public ClassVerifier(final ClassVisitor classVisitor) { // Make sure use we don't use Java 9 or higher classfile features. // We also want to make sure we don't use Java 6, 7 or 8 classfile // features (invokedynamic), but this can't be done in the same way. // Instead, we use manual checks below. super(Opcodes.ASM4, classVisitor); - ok = true; } @Override @@ -206,8 +191,7 @@ public final class Retrofitter { final String superName, final String[] interfaces) { if ((version & 0xFFFF) > Opcodes.V1_5) { - System.err.println("ERROR: " + name + " version is newer than 1.5"); - ok = false; + throw new IllegalArgumentException("ERROR: " + name + " version is newer than 1.5"); } className = name; super.visit(version, access, name, signature, superName, interfaces); @@ -247,22 +231,20 @@ public final class Retrofitter { if (value instanceof Type) { int sort = ((Type) value).getSort(); if (sort == Type.METHOD) { - System.err.println( + throw new IllegalArgumentException( "ERROR: ldc with a MethodType called in " + className + ' ' + currentMethodName + " is not available in JDK 1.5"); - ok = false; } } else if (value instanceof Handle) { - System.err.println( + throw new IllegalArgumentException( "ERROR: ldc with a MethodHandle called in " + className + ' ' + currentMethodName + " is not available in JDK 1.5"); - ok = false; } super.visitLdcInsn(value); } @@ -273,15 +255,12 @@ public final class Retrofitter { final String descriptor, final Handle bootstrapMethodHandle, final Object... bootstrapMethodArguments) { - System.err.println( + throw new IllegalArgumentException( "ERROR: invokedynamic called in " + className + ' ' + currentMethodName + " is not available in JDK 1.5"); - ok = false; - super.visitInvokeDynamicInsn( - name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments); } }; } @@ -294,14 +273,14 @@ public final class Retrofitter { */ void check(final String owner, final String member) { if (owner.startsWith("java/")) { - String o = owner; - while (o != null) { - if (API.contains(o + ' ' + member)) { + String currentOwner = owner; + while (currentOwner != null) { + if (jdkApi.contains(currentOwner + ' ' + member)) { return; } - o = HIERARCHY.get(o); + currentOwner = jdkHierarchy.get(currentOwner); } - System.err.println( + throw new IllegalArgumentException( "ERROR: " + owner + ' ' @@ -311,7 +290,6 @@ public final class Retrofitter { + ' ' + currentMethodName + " is not defined in the JDK 1.5 API"); - ok = false; } } }