Search in sources :

Example 1 with InnerClass

use of org.apache.bcel.classfile.InnerClass in project wcomponents by BorderTech.

the class CheckComponentModelDefinition method visitClassContext.

/**
 * {@inheritDoc}
 */
@Override
public void visitClassContext(final ClassContext classContext) {
    if (!util.isComponentModel(classContext.getJavaClass())) {
        return;
    }
    // TODO: This is nasty, but classContext.getXClass().isStatic() returns FALSE for static inner classes.
    boolean isStatic = false;
    if (classContext.getXClass().getImmediateEnclosingClass() != null) {
        for (Attribute attribute : classContext.getJavaClass().getAttributes()) {
            if (attribute instanceof InnerClasses) {
                InnerClass inner = ((InnerClasses) attribute).getInnerClasses()[0];
                isStatic = (inner.getInnerAccessFlags() & IClassConstants.ACC_STATIC) != 0;
                break;
            }
        }
    }
    if (!classContext.getXClass().isPublic() || classContext.getClassDescriptor().isAnonymousClass()) {
        reportBug(classContext);
    } else if (classContext.getXClass().getImmediateEnclosingClass() != null && !isStatic) {
        reportBug(classContext);
    } else {
        boolean foundPublicNoArgsConstructor = false;
        boolean foundConstructor = false;
        for (XMethod method : classContext.getXClass().getXMethods()) {
            if ("<init>".equals(method.getMethodDescriptor().getName())) {
                foundConstructor = true;
                if (method.isPublic() && method.getNumParams() == 0) {
                    foundPublicNoArgsConstructor = true;
                    break;
                }
            }
        }
        if (foundConstructor && !foundPublicNoArgsConstructor) {
            reportBug(classContext);
        }
    }
}
Also used : Attribute(org.apache.bcel.classfile.Attribute) XMethod(edu.umd.cs.findbugs.ba.XMethod) InnerClass(org.apache.bcel.classfile.InnerClass) InnerClasses(org.apache.bcel.classfile.InnerClasses)

Example 2 with InnerClass

use of org.apache.bcel.classfile.InnerClass in project jop by jop-devel.

the class InnerClassesInfo method getDirectInnerClassNames.

/**
 * Get a list of fully qualified classnames of all direct inner classes of this class, including local classes,
 * using the InnerClasses attribute.
 *
 * @return a collection of fully qualified classnames of the inner classes or an empty collection if this class
 *   has no inner classes.
 */
public Collection<String> getDirectInnerClassNames() {
    InnerClasses ic = getInnerClassesAttribute();
    if (ic == null) {
        return new LinkedList<String>();
    }
    List<String> inner = new LinkedList<String>();
    for (InnerClass i : ic.getInnerClasses()) {
        String outerName = getOuterClassName(i);
        if (getInnerClassName(i).equals(getClassName())) {
            continue;
        }
        // if outer is null, inner is a local inner class of this class.
        if (outerName == null || getClassName().equals(outerName)) {
            inner.add(getInnerClassName(i));
        }
    }
    return inner;
}
Also used : InnerClass(org.apache.bcel.classfile.InnerClass) InnerClasses(org.apache.bcel.classfile.InnerClasses) LinkedList(java.util.LinkedList)

Example 3 with InnerClass

use of org.apache.bcel.classfile.InnerClass 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)

Example 4 with InnerClass

use of org.apache.bcel.classfile.InnerClass in project jop by jop-devel.

the class InnerClassesInfo method buildInnerClasses.

/**
 * Build a map of InnerClasses containing all entries for all inner classes in the 'classes'
 * parameter and all their enclosing inner classes.
 *
 * @param classes a collection of classes the result should contain.
 * @return the map of className->InnerClass containing all inner classes in the 'classes' parameter.
 */
private Collection<InnerClass> buildInnerClasses(Collection<ClassRef> classes) {
    List<ClassRef> queue = new LinkedList<ClassRef>(classes);
    Set<String> visited = new HashSet<String>();
    List<InnerClass> inner = new LinkedList<InnerClass>();
    ConstantPoolGen cpg = classGen.getConstantPool();
    InnerClasses ic = getInnerClassesAttribute();
    while (!queue.isEmpty()) {
        ClassRef ref = queue.remove(0);
        ClassInfo cls = ref.getClassInfo();
        int innerClassIdx;
        int outerClassIdx = 0;
        int innerNameIdx = 0;
        int flags = 0;
        String enclosingClass = null;
        if (cls != null) {
            InnerClassesInfo info = cls.getInnerClassesInfo();
            // only nested classes have an entry
            if (!info.isNestedClass()) {
                continue;
            }
            enclosingClass = info.getEnclosingClassName();
            innerClassIdx = cpg.addClass(ref.getClassName());
            if (!info.isLocalInnerClass()) {
                // class is a member, add outer class reference
                outerClassIdx = cpg.addClass(enclosingClass);
            }
            if (!info.isAnonymousInnerClass()) {
                // class has a simple name
                innerNameIdx = cpg.addUtf8(info.getInnerName());
            }
            flags = cls.getAccessFlags();
        } else {
            // unknown class, need to check the existing InnerClass array, if it exists
            InnerClass i = findInnerClass(ic, ref.getClassName());
            if (i == null) {
                // class is not an innerclass according to our old InnerClasses table
                continue;
            }
            innerClassIdx = i.getInnerClassIndex();
            outerClassIdx = i.getOuterClassIndex();
            innerNameIdx = i.getInnerNameIndex();
            flags = i.getInnerAccessFlags();
        }
        // will add a reference to the enclosing class anyway
        if (enclosingClass != null && !visited.contains(enclosingClass)) {
            queue.add(classInfo.getAppInfo().getClassRef(enclosingClass));
        }
        visited.add(ref.getClassName());
        inner.add(new InnerClass(innerClassIdx, outerClassIdx, innerNameIdx, flags));
    }
    return inner;
}
Also used : ClassRef(com.jopdesign.common.type.ClassRef) InnerClasses(org.apache.bcel.classfile.InnerClasses) LinkedList(java.util.LinkedList) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) InnerClass(org.apache.bcel.classfile.InnerClass) HashSet(java.util.HashSet) ConstantClassInfo(com.jopdesign.common.type.ConstantClassInfo)

Example 5 with InnerClass

use of org.apache.bcel.classfile.InnerClass in project jop by jop-devel.

the class InnerClassesInfo method isNestedClass.

/**
 * Check if the given classRef is a nested class (not necessarily of this class!),
 * using the InnerClasses attribute of this class if no ClassInfo is available for the reference.
 *
 * @param classRef the class to check using the InnerClasses attribute of this class.
 * @return true if the referenced class is a nested class or if this class knows the class as nested class.
 */
public boolean isNestedClass(ClassRef classRef) {
    ClassInfo classInfo = classRef.getClassInfo();
    if (classInfo != null) {
        return classInfo.isNestedClass();
    }
    InnerClass ic = getInnerClassAttribute(classRef.getClassName());
    return ic != null;
}
Also used : InnerClass(org.apache.bcel.classfile.InnerClass) ConstantClassInfo(com.jopdesign.common.type.ConstantClassInfo)

Aggregations

InnerClass (org.apache.bcel.classfile.InnerClass)5 InnerClasses (org.apache.bcel.classfile.InnerClasses)4 LinkedList (java.util.LinkedList)3 ClassRef (com.jopdesign.common.type.ClassRef)2 ConstantClassInfo (com.jopdesign.common.type.ConstantClassInfo)2 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)2 XMethod (edu.umd.cs.findbugs.ba.XMethod)1 HashSet (java.util.HashSet)1 Attribute (org.apache.bcel.classfile.Attribute)1