Search in sources :

Example 1 with ClassRef

use of com.jopdesign.common.type.ClassRef in project jop by jop-devel.

the class ClinitOrder method findDependencies.

private Set<ClassInfo> findDependencies(MethodInfo method, boolean inRec) {
    //		System.out.println("find dep. in "+cli.clazz.getClassName()+":"+mi.getMethod().getName());
    Set<ClassInfo> depends = new HashSet<ClassInfo>();
    if (method.isNative() || method.isAbstract()) {
        // subclasses???? :-(
        return depends;
    }
    ClassInfo classInfo = method.getClassInfo();
    ConstantPoolGen cpoolgen = method.getConstantPoolGen();
    InstructionList il = method.getCode().getInstructionList();
    InstructionFinder f = new InstructionFinder(il);
    // TODO can we encounter an empty instruction list?
    //if(il.getStart() == null) {
    //    return depends;
    //}
    // find instructions that access the constant pool
    // collect all indices to constants in ClassInfo
    String cpInstr = "CPInstruction";
    for (Iterator it = f.search(cpInstr); it.hasNext(); ) {
        InstructionHandle[] match = (InstructionHandle[]) it.next();
        InstructionHandle first = match[0];
        CPInstruction ii = (CPInstruction) first.getInstruction();
        int idx = ii.getIndex();
        Constant co = cpoolgen.getConstant(idx);
        ClassRef classRef = null;
        Set addDepends = null;
        ClassInfo clinfo;
        MethodInfo minfo;
        switch(co.getTag()) {
            case Constants.CONSTANT_Class:
                classRef = classInfo.getConstantInfo(co).getClassRef();
                clinfo = classRef.getClassInfo();
                if (clinfo != null) {
                    minfo = clinfo.getMethodInfo("<init>()V");
                    if (minfo != null) {
                        addDepends = findDependencies(minfo, true);
                    }
                }
                break;
            case Constants.CONSTANT_Fieldref:
            case Constants.CONSTANT_InterfaceMethodref:
                classRef = classInfo.getConstantInfo(co).getClassRef();
                break;
            case Constants.CONSTANT_Methodref:
                ConstantMethodInfo mref = (ConstantMethodInfo) classInfo.getConstantInfo(co);
                classRef = mref.getClassRef();
                minfo = mref.getMethodRef().getMethodInfo();
                if (minfo != null) {
                    addDepends = findDependencies(minfo, true);
                }
                break;
        }
        if (classRef != null) {
            ClassInfo clinf = classRef.getClassInfo();
            if (clinf != null) {
                if (clinf.getMethodInfo(clinitSig) != null) {
                    // don't add myself as dependency
                    if (!clinf.equals(method.getClassInfo())) {
                        depends.add(clinf);
                    }
                }
            }
        }
        if (addDepends != null) {
            for (Object addDepend : addDepends) {
                ClassInfo addCli = (ClassInfo) addDepend;
                if (addCli.equals(method.getClassInfo())) {
                    throw new JavaClassFormatError("cyclic indirect <clinit> dependency");
                }
                depends.add(addCli);
            }
        }
    }
    return depends;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) ClassRef(com.jopdesign.common.type.ClassRef) InstructionList(org.apache.bcel.generic.InstructionList) Constant(org.apache.bcel.classfile.Constant) InstructionFinder(org.apache.bcel.util.InstructionFinder) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ConstantMethodInfo(com.jopdesign.common.type.ConstantMethodInfo) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) CPInstruction(org.apache.bcel.generic.CPInstruction) JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) Iterator(java.util.Iterator) MethodInfo(com.jopdesign.common.MethodInfo) ConstantMethodInfo(com.jopdesign.common.type.ConstantMethodInfo) HashSet(java.util.HashSet) ClassInfo(com.jopdesign.common.ClassInfo)

Example 2 with ClassRef

use of com.jopdesign.common.type.ClassRef in project jop by jop-devel.

the class AppInfo method getMethodRef.

/**
     * Get a reference to a method using the given memberID.
     * If the method is defined only in a (known) superclass and is inherited by this class,
     * get a methodRef which contains a ClassRef to the given class but a MethodInfo from the superclass.
     * <p>
     * If you already have a classRef, use {@link #getMethodRef(ClassRef, MemberID)}
     * instead.
     * </p>
     * @param memberID the memberID of the method
     * @param isInterfaceMethod true if the class is an interface.
     * @return a method reference with or without MethodInfo or ClassInfo.
     */
public MethodRef getMethodRef(MemberID memberID, boolean isInterfaceMethod) {
    ClassInfo cls = classes.get(memberID.getClassName());
    ClassRef clsRef;
    if (cls != null) {
        if (cls.isInterface() != isInterfaceMethod) {
            throw new ClassFormatException("Class '" + cls.getClassName() + "' interface flag does not match.");
        }
        clsRef = cls.getClassRef();
    } else {
        clsRef = new ClassRef(memberID.getClassName(), isInterfaceMethod);
    }
    return getMethodRef(clsRef, memberID);
}
Also used : ClassRef(com.jopdesign.common.type.ClassRef) ClassFormatException(org.apache.bcel.classfile.ClassFormatException)

Example 3 with ClassRef

use of com.jopdesign.common.type.ClassRef in project jop by jop-devel.

the class AppInfo method getFieldRef.

public FieldRef getFieldRef(String className, String fieldName) {
    ClassInfo cls = classes.get(className);
    ClassRef clsRef;
    if (cls != null) {
        FieldInfo field = cls.getFieldInfo(fieldName);
        if (field != null) {
            return field.getFieldRef();
        }
        clsRef = cls.getClassRef();
    } else {
        clsRef = new ClassRef(className);
    }
    return new FieldRef(clsRef, fieldName, null);
}
Also used : FieldRef(com.jopdesign.common.type.FieldRef) ClassRef(com.jopdesign.common.type.ClassRef)

Example 4 with ClassRef

use of com.jopdesign.common.type.ClassRef in project jop by jop-devel.

the class AppInfo method getMethodRef.

public MethodRef getMethodRef(MemberID memberID) {
    ClassInfo cls = classes.get(memberID.getClassName());
    ClassRef clsRef;
    if (cls != null) {
        clsRef = cls.getClassRef();
    } else {
        clsRef = new ClassRef(memberID.getClassName());
    }
    return getMethodRef(clsRef, memberID);
}
Also used : ClassRef(com.jopdesign.common.type.ClassRef)

Example 5 with ClassRef

use of com.jopdesign.common.type.ClassRef in project jop by jop-devel.

the class InnerClassesInfo method buildInnerClassesAttribute.

/*
     * Make this class a member nested class of the given class or move it to top-level
     *
     * @param enclosingClass the new outer class of this class, or null to make it a toplevel class.
     * @param innerName the simple name of this member class.
     */
/*
    public void setEnclosingClass(ClassInfo enclosingClass, String innerName) throws AppInfoException {
        // implement setOuterClass(), if needed. But this is not a simple task.
        // need to
        // - remove references to old outerClass from InnerClasses of this and all old outer classes
        // - create InnerClasses attribute if none exists
        // - add new entries to InnerClasses of this and all new outer classes.
        // - update class hierarchy infos and fullyKnown flags
        // - handle setEnclosingClass(null)
    }
    */
/*
     * Make this class a local nested class of the given method.
     * @param methodInfo the enclosing method of this class.
     */
/*
    public void setEnclosingMethod(MethodInfo methodInfo) {
    }
    */
/*
     * Add or replace InnerClass entries of this class with the info of the given classes.
     * If no InnerClasses attribute exists, it is created. Enclosing classes are added if needed.
     *
     * @param nestedClasses a list of nested classes to add to the InnerClasses attribute.
     */
/*
    public void addInnerClassRefs(Collection<ClassRef> nestedClasses) {
        if ( nestedClasses == null || nestedClasses.isEmpty() ) {
            return;
        }

        Map<String, InnerClass> classes = buildInnerClasses(nestedClasses);

        // create an InnerClasses attribute if it does not exist
        // add all InnerClasses to the existing InnerClasses (replace entries if existing)
    }
    */
/**
     * Build a new InnerClasses Attribute containing entries for all inner classes referenced by the current
     * constantpool, using the current ClassInfos or the old InnerClasses attribute to build the table.
     *
     * @return a new InnerClasses attribute or null if this class does not reference any inner classes.
     */
public InnerClasses buildInnerClassesAttribute() {
    ConstantPoolGen cpg = classGen.getConstantPool();
    // check+update InnerClasses attribute (and add referenced nested classes)
    List<ClassRef> referencedClasses = new LinkedList<ClassRef>();
    for (String name : ConstantPoolReferenceFinder.findReferencedClasses(classInfo)) {
        referencedClasses.add(classInfo.getAppInfo().getClassRef(name));
    }
    // find all referenced classes recursively, build InnerClass list from ClassInfo or old InnerClasses
    Collection<InnerClass> classes = buildInnerClasses(referencedClasses);
    if (classes.isEmpty()) {
        return null;
    }
    InnerClass[] ics = null;
    ics = classes.toArray(ics);
    int length = ics.length * 8 + 2;
    return new InnerClasses(cpg.addUtf8("InnerClasses"), length, ics, cpg.getConstantPool());
}
Also used : ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) ClassRef(com.jopdesign.common.type.ClassRef) InnerClass(org.apache.bcel.classfile.InnerClass) InnerClasses(org.apache.bcel.classfile.InnerClasses) LinkedList(java.util.LinkedList)

Aggregations

ClassRef (com.jopdesign.common.type.ClassRef)6 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)3 HashSet (java.util.HashSet)2 LinkedList (java.util.LinkedList)2 InnerClass (org.apache.bcel.classfile.InnerClass)2 InnerClasses (org.apache.bcel.classfile.InnerClasses)2 ClassInfo (com.jopdesign.common.ClassInfo)1 MethodInfo (com.jopdesign.common.MethodInfo)1 JavaClassFormatError (com.jopdesign.common.misc.JavaClassFormatError)1 ConstantClassInfo (com.jopdesign.common.type.ConstantClassInfo)1 ConstantMethodInfo (com.jopdesign.common.type.ConstantMethodInfo)1 FieldRef (com.jopdesign.common.type.FieldRef)1 Iterator (java.util.Iterator)1 Set (java.util.Set)1 ClassFormatException (org.apache.bcel.classfile.ClassFormatException)1 Constant (org.apache.bcel.classfile.Constant)1 CPInstruction (org.apache.bcel.generic.CPInstruction)1 InstructionHandle (org.apache.bcel.generic.InstructionHandle)1 InstructionList (org.apache.bcel.generic.InstructionList)1 InstructionFinder (org.apache.bcel.util.InstructionFinder)1