org.robolectric.internal.bytecode.ClassDetails Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sandbox Show documentation
Show all versions of sandbox Show documentation
An alternative Android testing framework.
The newest version!
package org.robolectric.internal.bytecode;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
/**
* A more lightweight variant of {@link MutableClass}. This lets you check for basic metadata like
* class name, interfaces, and annotation info by wrapping a {@link ClassReader}, which is
* significantly faster than a {@link org.objectweb.asm.tree.ClassNode} object.
*/
public class ClassDetails {
private static final String SHADOWED_OBJECT_INTERNAL_NAME =
ShadowedObject.class.getName().replace('.', '/');
private static final String INSTRUMENTED_INTERFACE_INTERNAL_NAME =
InstrumentedInterface.class.getName().replace('.', '/');
private final ClassReader classReader;
private final String className;
private final byte[] classBytes;
private Set annotations;
private Set interfaces;
public ClassDetails(byte[] classBytes) {
this.classBytes = classBytes;
this.classReader = new ClassReader(classBytes);
this.className = classReader.getClassName().replace('/', '.');
}
public boolean isInterface() {
return (classReader.getAccess() & Opcodes.ACC_INTERFACE) != 0;
}
public boolean isAnnotation() {
return (classReader.getAccess() & Opcodes.ACC_ANNOTATION) != 0;
}
public String getName() {
return className;
}
public boolean hasAnnotation(String annotationClassName) {
if (annotations == null) {
this.annotations = new HashSet<>();
classReader.accept(
new AnnotationCollector(annotations),
ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
}
String internalName = "L" + annotationClassName.replace('.', '/') + ";";
return this.annotations.contains(internalName);
}
public boolean hasAnnotation(Class extends Annotation> annotationClass) {
return hasAnnotation(annotationClass.getName());
}
public boolean isInstrumented() {
if (this.interfaces == null) {
this.interfaces = new HashSet<>(Arrays.asList(classReader.getInterfaces()));
}
return (isInterface() && this.interfaces.contains(INSTRUMENTED_INTERFACE_INTERNAL_NAME))
|| this.interfaces.contains(SHADOWED_OBJECT_INTERNAL_NAME);
}
public byte[] getClassBytes() {
return classBytes;
}
private static class AnnotationCollector extends ClassVisitor {
private final Set annotations;
public AnnotationCollector(Set annotations) {
super(Opcodes.ASM9);
this.annotations = annotations;
}
@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
if (visible) {
annotations.add(descriptor);
}
return null;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy