Search in sources :

Example 6 with InnerClassNode

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);
    }
}
Also used : InnerClassNode(org.objectweb.asm.tree.InnerClassNode)

Example 7 with InnerClassNode

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");
}
Also used : LinkedHashSet(java.util.LinkedHashSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) GenericMethod(org.evosuite.utils.generic.GenericMethod) GenericField(org.evosuite.utils.generic.GenericField) Field(java.lang.reflect.Field) GenericClass(org.evosuite.utils.generic.GenericClass) InnerClassNode(org.objectweb.asm.tree.InnerClassNode) ClassNode(org.objectweb.asm.tree.ClassNode) GenericConstructor(org.evosuite.utils.generic.GenericConstructor) GenericMethod(org.evosuite.utils.generic.GenericMethod) Method(java.lang.reflect.Method) MethodIdentifier(org.evosuite.setup.PutStaticMethodCollector.MethodIdentifier) InnerClassNode(org.objectweb.asm.tree.InnerClassNode) LinkedList(java.util.LinkedList) GenericClass(org.evosuite.utils.generic.GenericClass) GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) GenericField(org.evosuite.utils.generic.GenericField)

Example 8 with InnerClassNode

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);
                }
            }
        }
    }
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) InnerClassNode(org.objectweb.asm.tree.InnerClassNode) FieldNode(org.objectweb.asm.tree.FieldNode) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InnerClassNode(org.objectweb.asm.tree.InnerClassNode) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode)

Example 9 with InnerClassNode

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();
}
Also used : InnerClassNode(org.objectweb.asm.tree.InnerClassNode) ClassNode(org.objectweb.asm.tree.ClassNode) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) StringWriter(java.io.StringWriter) ArrayList(java.util.ArrayList) ClassReader(org.objectweb.asm.ClassReader) InnerClassNode(org.objectweb.asm.tree.InnerClassNode) PrintWriter(java.io.PrintWriter)

Example 10 with InnerClassNode

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;
}
Also used : InnerClassNode(org.objectweb.asm.tree.InnerClassNode)

Aggregations

InnerClassNode (org.objectweb.asm.tree.InnerClassNode)14 ArrayList (java.util.ArrayList)6 ClassNode (org.objectweb.asm.tree.ClassNode)5 MethodNode (org.objectweb.asm.tree.MethodNode)4 FieldNode (org.objectweb.asm.tree.FieldNode)3 IrMethod (com.googlecode.dex2jar.ir.IrMethod)2 PrintWriter (java.io.PrintWriter)2 TraceClassVisitor (org.objectweb.asm.util.TraceClassVisitor)2 StringWriter (java.io.StringWriter)1 Field (java.lang.reflect.Field)1 Method (java.lang.reflect.Method)1 Comparator (java.util.Comparator)1 LinkedHashSet (java.util.LinkedHashSet)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Set (java.util.Set)1 MethodIdentifier (org.evosuite.setup.PutStaticMethodCollector.MethodIdentifier)1 GenericAccessibleObject (org.evosuite.utils.generic.GenericAccessibleObject)1 GenericClass (org.evosuite.utils.generic.GenericClass)1 GenericConstructor (org.evosuite.utils.generic.GenericConstructor)1