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);
}
}
}
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;
}
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());
}
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;
}
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;
}
Aggregations