Commit 9d240820 authored by Eric Bruneton's avatar Eric Bruneton

Improve the code quality and coverage of the util package tests.

parent c0f7167d
Pipeline #527 passed with stage
in 10 minutes and 40 seconds
......@@ -28,6 +28,7 @@
package org.objectweb.asm.util;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
......@@ -64,6 +65,23 @@ public class ASMifier extends Printer {
private static final String END_PARAMETERS = ");\n\n";
private static final String VISIT_END = ".visitEnd();\n";
private static final Map<Integer, String> CLASS_VERSIONS;
static {
HashMap<Integer, String> classVersions = new HashMap<Integer, String>();
classVersions.put(Opcodes.V1_1, "V1_1");
classVersions.put(Opcodes.V1_2, "V1_2");
classVersions.put(Opcodes.V1_3, "V1_3");
classVersions.put(Opcodes.V1_4, "V1_4");
classVersions.put(Opcodes.V1_5, "V1_5");
classVersions.put(Opcodes.V1_6, "V1_6");
classVersions.put(Opcodes.V1_7, "V1_7");
classVersions.put(Opcodes.V1_8, "V1_8");
classVersions.put(Opcodes.V9, "V9");
classVersions.put(Opcodes.V10, "V10");
CLASS_VERSIONS = Collections.unmodifiableMap(classVersions);
}
/** The name of the visitor variable in the produced code. */
protected final String name;
......@@ -160,40 +178,11 @@ public class ASMifier extends Printer {
stringBuilder.setLength(0);
stringBuilder.append("classWriter.visit(");
switch (version) {
case Opcodes.V1_1:
stringBuilder.append("V1_1");
break;
case Opcodes.V1_2:
stringBuilder.append("V1_2");
break;
case Opcodes.V1_3:
stringBuilder.append("V1_3");
break;
case Opcodes.V1_4:
stringBuilder.append("V1_4");
break;
case Opcodes.V1_5:
stringBuilder.append("V1_5");
break;
case Opcodes.V1_6:
stringBuilder.append("V1_6");
break;
case Opcodes.V1_7:
stringBuilder.append("V1_7");
break;
case Opcodes.V1_8:
stringBuilder.append("V1_8");
break;
case Opcodes.V9:
stringBuilder.append("V9");
break;
case Opcodes.V10:
stringBuilder.append("V10");
break;
default:
stringBuilder.append(version);
break;
String versionString = CLASS_VERSIONS.get(version);
if (versionString != null) {
stringBuilder.append(versionString);
} else {
stringBuilder.append(version);
}
stringBuilder.append(", ");
appendAccessFlags(access | ACCESS_CLASS);
......
......@@ -560,7 +560,7 @@ public class CheckClassAdapter extends ClassVisitor {
throw new IllegalArgumentException(
"Invalid type reference sort 0x" + Integer.toHexString(sort));
}
checkTypeRefAndPath(typeRef, typePath);
checkTypeRef(typeRef);
CheckMethodAdapter.checkDescriptor(descriptor, false);
return new CheckAnnotationAdapter(
super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
......@@ -721,72 +721,6 @@ public class CheckClassAdapter extends ClassVisitor {
}
}
/**
* Checks the reference to a type in a type annotation.
*
* @param typeRef a reference to an annotated type.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or
* static inner type within 'typeRef'. May be <tt>null</tt> if the annotation targets
* 'typeRef' as a whole.
*/
static void checkTypeRefAndPath(final int typeRef, final TypePath typePath) {
int mask = 0;
switch (typeRef >>> 24) {
case TypeReference.CLASS_TYPE_PARAMETER:
case TypeReference.METHOD_TYPE_PARAMETER:
case TypeReference.METHOD_FORMAL_PARAMETER:
mask = 0xFFFF0000;
break;
case TypeReference.FIELD:
case TypeReference.METHOD_RETURN:
case TypeReference.METHOD_RECEIVER:
case TypeReference.LOCAL_VARIABLE:
case TypeReference.RESOURCE_VARIABLE:
case TypeReference.INSTANCEOF:
case TypeReference.NEW:
case TypeReference.CONSTRUCTOR_REFERENCE:
case TypeReference.METHOD_REFERENCE:
mask = 0xFF000000;
break;
case TypeReference.CLASS_EXTENDS:
case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
case TypeReference.THROWS:
case TypeReference.EXCEPTION_PARAMETER:
mask = 0xFFFFFF00;
break;
case TypeReference.CAST:
case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
mask = 0xFF0000FF;
break;
default:
throw new IllegalArgumentException(
"Invalid type reference sort 0x" + Integer.toHexString(typeRef >>> 24));
}
if ((typeRef & ~mask) != 0) {
throw new IllegalArgumentException(
"Invalid type reference 0x" + Integer.toHexString(typeRef));
}
if (typePath != null) {
for (int i = 0; i < typePath.getLength(); ++i) {
int step = typePath.getStep(i);
if (step != TypePath.ARRAY_ELEMENT
&& step != TypePath.INNER_TYPE
&& step != TypePath.TYPE_ARGUMENT
&& step != TypePath.WILDCARD_BOUND) {
throw new IllegalArgumentException("Invalid type path step " + i + " in " + typePath);
}
if (step != TypePath.TYPE_ARGUMENT && typePath.getStepArgument(i) != 0) {
throw new IllegalArgumentException(
"Invalid type path step argument for step " + i + " in " + typePath);
}
}
}
}
/**
* Checks the type parameters of a class or method signature.
*
......@@ -1031,4 +965,51 @@ public class CheckClassAdapter extends ClassVisitor {
private static char getChar(final String string, final int pos) {
return pos < string.length() ? string.charAt(pos) : (char) 0;
}
/**
* Checks the reference to a type in a type annotation.
*
* @param typeRef a reference to an annotated type.
*/
static void checkTypeRef(final int typeRef) {
int mask = 0;
switch (typeRef >>> 24) {
case TypeReference.CLASS_TYPE_PARAMETER:
case TypeReference.METHOD_TYPE_PARAMETER:
case TypeReference.METHOD_FORMAL_PARAMETER:
mask = 0xFFFF0000;
break;
case TypeReference.FIELD:
case TypeReference.METHOD_RETURN:
case TypeReference.METHOD_RECEIVER:
case TypeReference.LOCAL_VARIABLE:
case TypeReference.RESOURCE_VARIABLE:
case TypeReference.INSTANCEOF:
case TypeReference.NEW:
case TypeReference.CONSTRUCTOR_REFERENCE:
case TypeReference.METHOD_REFERENCE:
mask = 0xFF000000;
break;
case TypeReference.CLASS_EXTENDS:
case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
case TypeReference.THROWS:
case TypeReference.EXCEPTION_PARAMETER:
mask = 0xFFFFFF00;
break;
case TypeReference.CAST:
case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
mask = 0xFF0000FF;
break;
default:
throw new AssertionError();
}
if ((typeRef & ~mask) != 0) {
throw new IllegalArgumentException(
"Invalid type reference 0x" + Integer.toHexString(typeRef));
}
}
}
......@@ -85,7 +85,7 @@ public class CheckFieldAdapter extends FieldVisitor {
throw new IllegalArgumentException(
"Invalid type reference sort 0x" + Integer.toHexString(sort));
}
CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
CheckClassAdapter.checkTypeRef(typeRef);
CheckMethodAdapter.checkDescriptor(descriptor, false);
return new CheckAnnotationAdapter(
super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
......
......@@ -501,7 +501,7 @@ public class CheckMethodAdapter extends MethodVisitor {
&& sort != TypeReference.THROWS) {
throw new IllegalArgumentException(INVALID_TYPE_REFERENCE + Integer.toHexString(sort));
}
CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
CheckClassAdapter.checkTypeRef(typeRef);
CheckMethodAdapter.checkDescriptor(descriptor, false);
return new CheckAnnotationAdapter(
super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
......@@ -905,7 +905,7 @@ public class CheckMethodAdapter extends MethodVisitor {
&& sort != TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT) {
throw new IllegalArgumentException(INVALID_TYPE_REFERENCE + Integer.toHexString(sort));
}
CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
CheckClassAdapter.checkTypeRef(typeRef);
CheckMethodAdapter.checkDescriptor(descriptor, false);
return new CheckAnnotationAdapter(
super.visitInsnAnnotation(typeRef, typePath, descriptor, visible));
......@@ -941,7 +941,7 @@ public class CheckMethodAdapter extends MethodVisitor {
if (sort != TypeReference.EXCEPTION_PARAMETER) {
throw new IllegalArgumentException(INVALID_TYPE_REFERENCE + Integer.toHexString(sort));
}
CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
CheckClassAdapter.checkTypeRef(typeRef);
CheckMethodAdapter.checkDescriptor(descriptor, false);
return new CheckAnnotationAdapter(
super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible));
......@@ -986,7 +986,7 @@ public class CheckMethodAdapter extends MethodVisitor {
if (sort != TypeReference.LOCAL_VARIABLE && sort != TypeReference.RESOURCE_VARIABLE) {
throw new IllegalArgumentException(INVALID_TYPE_REFERENCE + Integer.toHexString(sort));
}
CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
CheckClassAdapter.checkTypeRef(typeRef);
checkDescriptor(descriptor, false);
if (start == null
|| end == null
......
......@@ -37,7 +37,7 @@ import org.objectweb.asm.Opcodes;
*
* @author Remi Forax
*/
public final class CheckModuleAdapter extends ModuleVisitor {
public class CheckModuleAdapter extends ModuleVisitor {
/** Whether the visited module is open. */
private final boolean isOpen;
......
......@@ -27,7 +27,11 @@
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringReader;
......@@ -46,6 +50,7 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.test.AsmTest;
/**
......@@ -60,24 +65,55 @@ public class ASMifierTest extends AsmTest {
new ClassLoaderIClassLoader(new URLClassLoader(new URL[0]));
@Test
public void testASMifierClassVisitor() throws Exception {
public void testConstructor() {
assertThrows(IllegalStateException.class, () -> new ASMifier() {});
}
@Test
public void testMain() throws IOException {
PrintStream err = System.err;
PrintStream out = System.out;
System.setErr(new PrintStream(new ByteArrayOutputStream()));
System.setOut(new PrintStream(new ByteArrayOutputStream()));
try {
String s = getClass().getName();
String thisClassName = getClass().getName();
String thisClassFilePath =
ClassLoader.getSystemResource(thisClassName.replace('.', '/') + ".class").getPath();
ASMifier.main(new String[0]);
ASMifier.main(new String[] {"-debug"});
ASMifier.main(new String[] {s});
ASMifier.main(new String[] {"-debug", s});
ASMifier.main(new String[] {thisClassName});
ASMifier.main(new String[] {thisClassFilePath});
ASMifier.main(new String[] {"-debug", thisClassName});
ASMifier.main(new String[] {"java.lang.Object"});
ASMifier.main(new String[] {"-debug", thisClassName, "extraArgument"});
assertThrows(IOException.class, () -> ASMifier.main(new String[] {"DoNotExist.class"}));
assertThrows(IOException.class, () -> ASMifier.main(new String[] {"do\\not\\exist"}));
} finally {
System.setErr(err);
System.setOut(out);
}
}
@Test
public void testBackwardCompatibility() {
ASMifier asmifier = new ASMifier();
asmifier.visitMethodInsn(Opcodes.INVOKESPECIAL, "owner", "name", "()V");
assertEquals(
"classWriter.visitMethodInsn(INVOKESPECIAL, \"owner\", \"name\", \"()V\", false);\n",
asmifier.getText().get(0));
}
@Test
public void testBackwardCompatibilityAsm4() {
ASMifier asmifier = new ASMifier(Opcodes.ASM4, "classWriter", 0) {};
asmifier.visitMethodInsn(Opcodes.INVOKESPECIAL, "owner", "name", "()V");
asmifier.visitMethodInsn(Opcodes.INVOKESPECIAL, "owner", "name", "()V", false);
String expectedText =
"classWriter.visitMethodInsn(INVOKESPECIAL, \"owner\", \"name\", \"()V\", false);\n";
assertEquals(expectedText, asmifier.getText().get(0));
assertEquals(expectedText, asmifier.getText().get(1));
}
/**
* Tests that the code produced with an ASMifier compiles and generates the original class.
*
......@@ -85,12 +121,12 @@ public class ASMifierTest extends AsmTest {
*/
@ParameterizedTest
@MethodSource(ALL_CLASSES_AND_LATEST_API)
public void testAsmifyCompileAndExecute(final PrecompiledClass classParameter, final Api apiParameter)
throws Exception {
public void testAsmifyCompileAndExecute(
final PrecompiledClass classParameter, final Api apiParameter) throws Exception {
byte[] classFile = classParameter.getBytes();
if (classFile.length > Short.MAX_VALUE) return;
// Produces the ASMified Java source code corresponding to classParameter.
// Produce the ASMified Java source code corresponding to classParameter.
StringWriter stringWriter = new StringWriter();
TraceClassVisitor classVisitor =
new TraceClassVisitor(null, new ASMifier(), new PrintWriter(stringWriter));
......@@ -98,7 +134,7 @@ public class ASMifierTest extends AsmTest {
.accept(classVisitor, new Attribute[] {new Comment(), new CodeComment()}, 0);
String asmifiedSource = stringWriter.toString();
// Compiles and executes this Java source code (skip JDK9 modules, Janino can't compile them).
// Compile and execute this Java source code (skip JDK9 modules, Janino can't compile them).
if (classParameter == PrecompiledClass.JDK9_MODULE) return;
byte[] asmifiedClassFile = compile(classParameter.getName(), asmifiedSource);
String asmifiedClassName = classParameter.getName() + "Dump";
......@@ -123,8 +159,8 @@ public class ASMifierTest extends AsmTest {
TestClassLoader() {}
public Class<?> defineClass(final String name, final byte[] b) {
return defineClass(name, b, 0, b.length);
public Class<?> defineClass(final String name, final byte[] classFile) {
return defineClass(name, classFile, 0, classFile.length);
}
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.util;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.test.AsmTest;
/**
* CheckAnnotationAdapter tests.
*
* @author Eric Bruneton
*/
public class CheckAnnotationAdapterTest extends AsmTest implements Opcodes {
private CheckAnnotationAdapter checkAnnotationAdapter = new CheckAnnotationAdapter(null);
@Test
public void testIllegalAnnotationName() {
assertThrows(Exception.class, () -> checkAnnotationAdapter.visit(null, new Integer(0)));
}
@Test
public void testIllegalAnnotationValue() {
assertThrows(Exception.class, () -> checkAnnotationAdapter.visit("name", new Object()));
assertThrows(
Exception.class, () -> checkAnnotationAdapter.visit("name", Type.getMethodType("()V")));
}
@Test
public void testIllegalAnnotationEnumValue() {
assertThrows(
Exception.class, () -> checkAnnotationAdapter.visitEnum("name", "Lpkg/Enum;", null));
}
@Test
public void testIllegalAnnotationValueAfterEnd() {
checkAnnotationAdapter.visitEnd();
assertThrows(Exception.class, () -> checkAnnotationAdapter.visit("name", new Integer(0)));
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.util;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.TypeReference;
import org.objectweb.asm.test.AsmTest;
/**
* CheckFieldAdapter tests.
*
* @author Eric Bruneton
*/
public class CheckFieldAdapterTest extends AsmTest implements Opcodes {
private CheckFieldAdapter checkFieldAdapter = new CheckFieldAdapter(null);
@Test
public void testConstructor() {
assertThrows(IllegalStateException.class, () -> new CheckFieldAdapter(null) {});
}
@Test
public void testIllegalFieldMemberVisitAfterEnd() {
checkFieldAdapter.visitEnd();
assertThrows(Exception.class, () -> checkFieldAdapter.visitAttribute(new Comment()));
}
@Test
public void testIllegalTypeAnnotation() {
assertThrows(
Exception.class,
() ->
checkFieldAdapter.visitTypeAnnotation(
TypeReference.newFormalParameterReference(0).getValue(), null, "LA;", true));
}
@Test
public void testIllegalFieldAttribute() {
assertThrows(Exception.class, () -> checkFieldAdapter.visitAttribute(null));
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.util;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
/**
* CheckModuleAdapter tests.
*
* @author Eric Bruneton
*/
public class CheckModuleAdapterTest {
private CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ false);
@Test
public void testConstructor() {
assertThrows(
IllegalStateException.class, () -> new CheckModuleAdapter(null, /* open = */ false) {});
}
@Test
public void testNullArraysSupported() {
checkModuleAdapter.visitExport("package", 0, (String[]) null);
checkModuleAdapter.visitOpen("package", 0, (String[]) null);
}
@Test
public void testIllegalOpen() {
checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ true);
assertThrows(
RuntimeException.class, () -> checkModuleAdapter.visitOpen("package", 0, (String[]) null));
}
@Test
public void testNameAlreadyDeclared() {
checkModuleAdapter.visitUse("service");
assertThrows(RuntimeException.class, () -> checkModuleAdapter.visitUse("service"));
}
@Test
public void testIllegalProvide() {
assertThrows(RuntimeException.class, () -> checkModuleAdapter.visitProvide("service1"));
assertThrows(
RuntimeException.class, () -> checkModuleAdapter.visitProvide("service2", (String[]) null));
}
@Test
public void testIllegalMemberVisitAfterEnd() {
checkModuleAdapter.visitEnd();
assertThrows(RuntimeException.class, () -> checkModuleAdapter.visitUse("service"));
}
}
This diff is collapsed.
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.Opcodes;
/**
* Textifier tests.
*
* @author Eugene Kuleshov
* @author Eric Bruneton
*/
public class TextifierTest {
@Test
public void testConstructor() {
assertThrows(IllegalStateException.class, () -> new Textifier() {});
}
@Test
public void testBackwardCompatibility() {
Textifier textifier = new Textifier();
textifier.visitMethodInsn(Opcodes.INVOKESPECIAL, "owner", "name", "()V");
assertEquals(" INVOKESPECIAL owner.name ()V\n", textifier.getText().get(0));
}
@Test
public void testBackwardCompatibilityAsm4() {
Textifier textifier = new Textifier(Opcodes.ASM4) {};
textifier.visitMethodInsn(Opcodes.INVOKESPECIAL, "owner", "name", "()V");
textifier.visitMethodInsn(Opcodes.INVOKESPECIAL, "owner", "name", "()V", false);
String expectedText = " INVOKESPECIAL owner.name ()V\n";
assertEquals(expectedText, textifier.getText().get(0));
assertEquals(expectedText, textifier.getText().get(1));
}
@Test
public void testMain() throws Exception {