use of org.objectweb.asm.tree.InnerClassNode in project MCPConfig by MinecraftForge.
the class MergeJar method processInners.
private static void processInners(ClassNode cClass, ClassNode sClass) {
List<InnerClassNode> cIners = cClass.innerClasses;
List<InnerClassNode> sIners = sClass.innerClasses;
for (InnerClassNode n : cIners) {
if (!contains(sIners, n))
sIners.add(n);
}
for (InnerClassNode n : sIners) {
if (!contains(cIners, n))
cIners.add(n);
}
}
use of org.objectweb.asm.tree.InnerClassNode in project evosuite by EvoSuite.
the class TestClusterGenerator method initializeTargetMethods.
/**
* All public methods defined directly in the SUT should be covered
*
* TODO: What if we use instrument_parent?
*/
@SuppressWarnings("unchecked")
private void initializeTargetMethods() throws RuntimeException, ClassNotFoundException {
logger.info("Analyzing target class");
Class<?> targetClass = Properties.getTargetClassAndDontInitialise();
TestCluster cluster = TestCluster.getInstance();
Set<Class<?>> targetClasses = new LinkedHashSet<Class<?>>();
if (targetClass == null) {
throw new RuntimeException("Failed to load " + Properties.TARGET_CLASS);
}
targetClasses.add(targetClass);
addDeclaredClasses(targetClasses, targetClass);
if (Modifier.isAbstract(targetClass.getModifiers())) {
logger.info("SUT is an abstract class");
Set<Class<?>> subclasses = ConcreteClassAnalyzer.getInstance().getConcreteClasses(targetClass, inheritanceTree);
logger.info("Found " + subclasses.size() + " concrete subclasses");
targetClasses.addAll(subclasses);
}
// load all the interesting classes from the callgraph,
// need more testing, seems to slow down the search
// if(Properties.INSTRUMENT_CONTEXT){
// Set<String> toLoad;
// if(Properties.INSTRUMENT_LIBRARIES){
// toLoad = callGraph.getClassesUnderTest();
// }else{
// toLoad = new HashSet<>();
// for (String className : callGraph.getClassesUnderTest()) {
// if (!Properties.INSTRUMENT_LIBRARIES
// && !DependencyAnalysis.isTargetProject(className))
// continue;
// toLoad.add(className);
// }
//
// }
// targetClasses.addAll(loadClasses(toLoad));
//
// }
// To make sure we also have anonymous inner classes double check inner
// classes using ASM
// because the loop changes 'targetClasses' set we cannot iterate over
// it, not even
// using an iterator. a simple workaround is to create a temporary set
// with the content
// of 'targetClasses' and iterate that one
Set<Class<?>> tmp_targetClasses = new LinkedHashSet<Class<?>>(targetClasses);
for (Class<?> _targetClass : tmp_targetClasses) {
ClassNode targetClassNode = DependencyAnalysis.getClassNode(_targetClass.getName());
Queue<InnerClassNode> innerClasses = new LinkedList<InnerClassNode>();
innerClasses.addAll(targetClassNode.innerClasses);
while (!innerClasses.isEmpty()) {
InnerClassNode icn = innerClasses.poll();
try {
logger.debug("Loading inner class: " + icn.innerName + ", " + icn.name + "," + icn.outerName);
String innerClassName = ResourceList.getClassNameFromResourcePath(icn.name);
if (!innerClassName.startsWith(Properties.TARGET_CLASS)) {
// TODO: Why does ASM report inner classes that are not actually inner classes?
// Let's ignore classes that don't start with the SUT name for now.
logger.debug("Ignoring inner class that is outside SUT {}", innerClassName);
continue;
}
Class<?> innerClass = TestGenerationContext.getInstance().getClassLoaderForSUT().loadClass(innerClassName);
// Sometimes strange things appear such as Map$Entry
if (!targetClasses.contains(innerClass) && /*
* FIXME: why all the checks were removed? without
* the following, for example
* com.google.javascript.jscomp.IdMappingUtil in
* 124_closure-compiler is not testable
*/
!innerClassName.contains("Map$Entry")) {
// && !innerClassName.matches(".*\\$\\d+(\\$.*)?$")) {
logger.info("Adding inner class {}", innerClassName);
targetClasses.add(innerClass);
ClassNode innerClassNode = DependencyAnalysis.getClassNode(innerClassName);
innerClasses.addAll(innerClassNode.innerClasses);
}
} catch (Throwable t) {
logger.error("Problem for " + Properties.TARGET_CLASS + ". Error loading inner class: " + icn.innerName + ", " + icn.name + "," + icn.outerName + ": " + t);
}
}
}
for (Class<?> clazz : targetClasses) {
logger.info("Current SUT class: " + clazz);
if (!TestUsageChecker.canUse(clazz)) {
logger.info("Cannot access SUT class: " + clazz);
continue;
}
// Add all constructors
for (Constructor<?> constructor : TestClusterUtils.getConstructors(clazz)) {
logger.info("Checking target constructor " + constructor);
String name = "<init>" + org.objectweb.asm.Type.getConstructorDescriptor(constructor);
if (Properties.TT) {
String orig = name;
name = BooleanTestabilityTransformation.getOriginalNameDesc(clazz.getName(), "<init>", org.objectweb.asm.Type.getConstructorDescriptor(constructor));
if (!orig.equals(name))
logger.info("TT name: " + orig + " -> " + name);
}
if (TestUsageChecker.canUse(constructor)) {
GenericConstructor genericConstructor = new GenericConstructor(constructor, clazz);
if (constructor.getDeclaringClass().equals(clazz))
cluster.addTestCall(genericConstructor);
// TODO: Add types!
// .getWithWildcardTypes(),
cluster.addGenerator(// .getWithWildcardTypes(),
new GenericClass(clazz), genericConstructor);
addDependencies(genericConstructor, 1);
logger.debug("Keeping track of " + constructor.getDeclaringClass().getName() + "." + constructor.getName() + org.objectweb.asm.Type.getConstructorDescriptor(constructor));
} else {
logger.debug("Constructor cannot be used: " + constructor);
}
}
// Add all methods
for (Method method : TestClusterUtils.getMethods(clazz)) {
logger.info("Checking target method " + method);
String name = method.getName() + org.objectweb.asm.Type.getMethodDescriptor(method);
if (Properties.TT) {
String orig = name;
name = BooleanTestabilityTransformation.getOriginalNameDesc(clazz.getName(), method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method));
if (!orig.equals(name))
logger.info("TT name: " + orig + " -> " + name);
}
if (TestUsageChecker.canUse(method, clazz)) {
logger.debug("Adding method " + clazz.getName() + "." + method.getName() + org.objectweb.asm.Type.getMethodDescriptor(method));
GenericMethod genericMethod = new GenericMethod(method, clazz);
if (method.getDeclaringClass().equals(clazz))
cluster.addTestCall(genericMethod);
// removed?
if (!CheapPurityAnalyzer.getInstance().isPure(method)) {
cluster.addModifier(new GenericClass(clazz), genericMethod);
}
addDependencies(genericMethod, 1);
GenericClass retClass = new GenericClass(method.getReturnType());
// if (!retClass.isPrimitive() && !retClass.isVoid() && !retClass.isObject())
if (!retClass.isVoid())
// .getWithWildcardTypes(),
cluster.addGenerator(// .getWithWildcardTypes(),
retClass, genericMethod);
} else {
logger.debug("Method cannot be used: " + method);
// If we do reflection on private methods, we still need to consider dependencies
if (Properties.P_REFLECTION_ON_PRIVATE > 0 && method.getDeclaringClass().equals(clazz)) {
GenericMethod genericMethod = new GenericMethod(method, clazz);
addDependencies(genericMethod, 1);
}
}
}
for (Field field : TestClusterUtils.getFields(clazz)) {
logger.info("Checking target field " + field);
if (TestUsageChecker.canUse(field, clazz)) {
GenericField genericField = new GenericField(field, clazz);
addDependencies(genericField, 1);
// .getWithWildcardTypes(),
cluster.addGenerator(// .getWithWildcardTypes(),
new GenericClass(field.getGenericType()), genericField);
logger.debug("Adding field " + field);
final boolean isFinalField = isFinalField(field);
if (!isFinalField) {
logger.debug("Is not final");
// Setting fields does not contribute to coverage, so we will only count it as a modifier
// if (field.getDeclaringClass().equals(clazz))
// cluster.addTestCall(new GenericField(field, clazz));
cluster.addModifier(new GenericClass(clazz), genericField);
} else {
logger.debug("Is final");
if (Modifier.isStatic(field.getModifiers()) && !field.getType().isPrimitive()) {
logger.debug("Is static non-primitive");
/*
* With this we are trying to cover such cases:
*
* public static final DurationField INSTANCE = new
* MillisDurationField();
*
* private MillisDurationField() { super(); }
*/
try {
Object o = field.get(null);
if (o == null) {
logger.info("Field is not yet initialized: " + field);
} else {
Class<?> actualClass = o.getClass();
logger.debug("Actual class is " + actualClass);
if (!actualClass.isAssignableFrom(genericField.getRawGeneratedType()) && genericField.getRawGeneratedType().isAssignableFrom(actualClass)) {
GenericField superClassField = new GenericField(field, clazz);
cluster.addGenerator(new GenericClass(actualClass), superClassField);
}
}
} catch (IllegalAccessException e) {
logger.error(e.getMessage());
}
}
}
} else {
logger.debug("Can't use field " + field);
// TODO: Duplicate code here
if (Properties.P_REFLECTION_ON_PRIVATE > 0) {
if (Modifier.isPrivate(field.getModifiers()) && !field.isSynthetic() && !field.getName().equals("serialVersionUID") && // primitives cannot be changed
!(field.getType().isPrimitive()) && // changing final strings also doesn't make much sense
!(Modifier.isFinal(field.getModifiers()) && field.getType().equals(String.class)) && // static fields lead to just too many problems... although this could be set as a parameter
!Modifier.isStatic(field.getModifiers())) {
GenericField genericField = new GenericField(field, clazz);
addDependencies(genericField, 1);
}
}
}
}
analyzedClasses.add(clazz);
// TODO: Set to generic type rather than class?
cluster.getAnalyzedClasses().add(clazz);
}
if (Properties.INSTRUMENT_PARENT) {
for (String superClass : inheritanceTree.getSuperclasses(Properties.TARGET_CLASS)) {
try {
Class<?> superClazz = TestGenerationContext.getInstance().getClassLoaderForSUT().loadClass(superClass);
dependencies.add(new DependencyPair(0, superClazz));
} catch (ClassNotFoundException e) {
logger.error("Problem for " + Properties.TARGET_CLASS + ". Class not found: " + superClass, e);
}
}
}
if (Properties.HANDLE_STATIC_FIELDS) {
GetStaticGraph getStaticGraph = GetStaticGraphGenerator.generate(Properties.TARGET_CLASS);
Map<String, Set<String>> staticFields = getStaticGraph.getStaticFields();
for (String className : staticFields.keySet()) {
logger.info("Adding static fields to cluster for class " + className);
Class<?> clazz;
try {
Sandbox.goingToExecuteUnsafeCodeOnSameThread();
clazz = TestClusterUtils.getClass(className);
} catch (ExceptionInInitializerError ex) {
logger.debug("Class class init caused exception " + className);
continue;
} finally {
Sandbox.doneWithExecutingUnsafeCodeOnSameThread();
}
if (clazz == null) {
logger.debug("Class not found " + className);
continue;
}
if (!TestUsageChecker.canUse(clazz))
continue;
Set<String> fields = staticFields.get(className);
for (Field field : TestClusterUtils.getFields(clazz)) {
if (!TestUsageChecker.canUse(field, clazz))
continue;
if (fields.contains(field.getName())) {
if (!isFinalField(field)) {
logger.debug("Is not final");
// cluster.addTestCall(new GenericField(field, clazz));
// Count static field as modifier of SUT, not as test call:
GenericField genericField = new GenericField(field, clazz);
cluster.addModifier(new GenericClass(Properties.getTargetClassAndDontInitialise()), genericField);
}
}
}
}
PutStaticMethodCollector collector = new PutStaticMethodCollector(Properties.TARGET_CLASS, staticFields);
Set<MethodIdentifier> methodIdentifiers = collector.collectMethods();
for (MethodIdentifier methodId : methodIdentifiers) {
Class<?> clazz = TestClusterUtils.getClass(methodId.getClassName());
if (clazz == null)
continue;
if (!TestUsageChecker.canUse(clazz))
continue;
Method method = TestClusterUtils.getMethod(clazz, methodId.getMethodName(), methodId.getDesc());
if (method == null)
continue;
GenericMethod genericMethod = new GenericMethod(method, clazz);
// Setting static fields is a modifier of a SUT
// cluster.addTestCall(genericMethod);
cluster.addModifier(new GenericClass(Properties.getTargetClassAndDontInitialise()), genericMethod);
}
}
logger.info("Finished analyzing target class");
}
use of org.objectweb.asm.tree.InnerClassNode in project bytecode-viewer by Konloch.
the class ASMResourceUtil method renameClassNode.
public static void renameClassNode(final String oldName, final String newName) {
for (ClassNode c : BytecodeViewer.getLoadedClasses()) {
for (InnerClassNode oo : c.innerClasses) {
if (oo.innerName != null && oo.innerName.equals(oldName))
oo.innerName = newName;
if (oo.name.equals(oldName))
oo.name = newName;
if (oo.outerName != null && oo.outerName.equals(oldName))
oo.outerName = newName;
}
if (c.signature != null)
c.signature = c.signature.replace(oldName, newName);
if (c.superName.equals(oldName))
c.superName = newName;
for (Object o : c.fields.toArray()) {
FieldNode f = (FieldNode) o;
f.desc = f.desc.replace(oldName, newName);
}
for (Object o : c.methods.toArray()) {
MethodNode m = (MethodNode) o;
if (m.localVariables != null)
for (LocalVariableNode node : m.localVariables) node.desc = node.desc.replace(oldName, newName);
if (m.signature != null)
m.signature = m.signature.replace(oldName, newName);
for (int i = 0; i < m.exceptions.size(); i++) if (m.exceptions.get(i).equals(oldName))
m.exceptions.set(i, newName);
for (AbstractInsnNode i : m.instructions.toArray()) {
if (i instanceof TypeInsnNode) {
TypeInsnNode t = (TypeInsnNode) i;
if (t.desc.equals(oldName))
t.desc = newName;
}
if (i instanceof MethodInsnNode) {
MethodInsnNode mi = (MethodInsnNode) i;
if (mi.owner.equals(oldName))
mi.owner = newName;
mi.desc = mi.desc.replace(oldName, newName);
}
if (i instanceof FieldInsnNode) {
FieldInsnNode fi = (FieldInsnNode) i;
if (fi.owner.equals(oldName))
fi.owner = newName;
fi.desc = fi.desc.replace(oldName, newName);
}
}
}
}
}
use of org.objectweb.asm.tree.InnerClassNode in project tycho by eclipse.
the class ClassfileComparator method disassemble.
private String disassemble(byte[] bytes) {
ClassReader reader = new ClassReader(bytes);
ClassNode clazz = new ClassNode();
reader.accept(clazz, Opcodes.ASM5 | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
// inner class list gets reordered during pack200 normalization
if (clazz.innerClasses != null) {
List<InnerClassNode> sorted = new ArrayList<>(clazz.innerClasses);
Collections.sort(sorted, new Comparator<InnerClassNode>() {
@Override
public int compare(InnerClassNode o1, InnerClassNode o2) {
return o1.name.compareTo(o2.name);
}
});
clazz.innerClasses = sorted;
}
// rendering human-readable bytecode is an eyecandy, we can compare ClassNodes directly
StringWriter buffer = new StringWriter();
PrintWriter writer = new PrintWriter(buffer);
clazz.accept(new TraceClassVisitor(writer));
writer.flush();
writer.close();
return buffer.toString();
}
use of org.objectweb.asm.tree.InnerClassNode in project evosuite by EvoSuite.
the class InheritanceTreeGenerator method canUse.
public static boolean canUse(ClassNode cn) {
if ((cn.access & Opcodes.ACC_PRIVATE) == Opcodes.ACC_PRIVATE) {
logger.debug(cn.name + " is private, ignoring it");
return false;
}
if (ANONYMOUS_MATCHER1.matcher(cn.name).matches()) {
logger.debug(cn.name + " looks like an anonymous class, ignoring it");
return false;
}
if (ANONYMOUS_MATCHER2.matcher(cn.name).matches()) {
logger.debug(cn.name + " looks like an anonymous class, ignoring it");
return false;
}
if (cn.name.startsWith("junit"))
return false;
// If the SUT is not in the default package, then
// we cannot import classes that are in the default
// package
/*
if ((cn.access & Opcodes.ACC_PUBLIC) != Opcodes.ACC_PUBLIC) {
String nameWithDots = cn.name.replace('/', '.');
String packageName = ClassUtils.getPackageName(nameWithDots);
if (!packageName.equals(Properties.CLASS_PREFIX)) {
return false;
}
}
*/
// ASM has some problem with the access of inner classes
// so we check if the inner class name is the current class name
// and if so, check if the inner class is actually accessible
@SuppressWarnings("unchecked") List<InnerClassNode> in = cn.innerClasses;
for (InnerClassNode inc : in) {
if (cn.name.equals(inc.name)) {
// logger.debug("ASM weird behaviour: Inner class equals class: " + inc.name);
if ((inc.access & Opcodes.ACC_PRIVATE) == Opcodes.ACC_PRIVATE) {
return false;
}
/*
if ((inc.access & Opcodes.ACC_PUBLIC) != Opcodes.ACC_PUBLIC) {
String nameWithDots = inc.name.replace('/', '.');
String packageName = ClassUtils.getPackageName(nameWithDots);
if (!packageName.equals(Properties.CLASS_PREFIX)) {
return false;
}
}
*/
logger.debug("Can use inner class: " + inc.name);
return true;
}
}
logger.debug(cn.name + " is accessible");
return true;
}
Aggregations