serp.bytecode.InnerClasses Maven / Gradle / Ivy
The newest version!
package serp.bytecode;
import java.io.*;
import java.util.*;
import serp.bytecode.visitor.*;
/**
* Attribute describing all referenced classes that are not package
* members. This includes all member interfaces and classes.
*
* @author Abe White
*/
public class InnerClasses extends Attribute {
private List _innerClasses = new LinkedList();
InnerClasses(int nameIndex, Attributes owner) {
super(nameIndex, owner);
}
/**
* Return all referenced inner classes, or empty array if none.
*/
public InnerClass[] getInnerClasses() {
return (InnerClass[]) _innerClasses.toArray
(new InnerClass[_innerClasses.size()]);
}
/**
* Return the inner class with the given name. If multiple inner classes
* share the name, which is returned is undefined. Use null to retrieve
* anonymous classes.
*/
public InnerClass getInnerClass(String name) {
InnerClass[] inners = getInnerClasses();
String inner;
for (int i = 0; i < inners.length; i++) {
inner = inners[i].getName();
if ((inner == null && name == null)
|| (inner != null && inner.equals(name)))
return inners[i];
}
return null;
}
/**
* Return all inner classes with the given name, or empty array if none.
* Use null to retrieve anonymous classes.
*/
public InnerClass[] getInnerClasses(String name) {
List matches = new LinkedList();
InnerClass[] inners = getInnerClasses();
String inner;
for (int i = 0; i < inners.length; i++) {
inner = inners[i].getName();
if ((inner == null && name == null)
|| (inner != null && inner.equals(name)))
matches.add(inners[i]);
}
return (InnerClass[]) matches.toArray(new InnerClass[matches.size()]);
}
/**
* Set the inner class references for this class. This method is
* useful when importing inner class references from another class.
*/
public void setInnerClasses(InnerClass[] inners) {
clear();
if (inners != null)
for (int i = 0; i < inners.length; i++)
addInnerClass(inners[i]);
}
/**
* Import an inner class from another entity, or make a copy of one
* on this entity.
*
* @return the newly added inner class
*/
public InnerClass addInnerClass(InnerClass inner) {
InnerClass newInner = addInnerClass(inner.getName(),
inner.getTypeName(), inner.getDeclarerName());
newInner.setAccessFlags(inner.getAccessFlags());
return newInner;
}
/**
* Add an inner class.
*/
public InnerClass addInnerClass() {
InnerClass inner = new InnerClass(this);
_innerClasses.add(inner);
return inner;
}
/**
* Add an inner class.
*
* @param name the simple name of the class, or null if anonymous
* @param type the full class name of the inner class
* @param owner the declaring class, or null if not a member class
*/
public InnerClass addInnerClass(String name, String type, String owner) {
InnerClass inner = addInnerClass();
inner.setName(name);
inner.setType(type);
inner.setDeclarer(owner);
return inner;
}
/**
* Add an inner class.
*
* @param name the simple name of the class, or null if anonymous
* @param type the class of the inner class
* @param owner the declaring class, or null if not a member class
*/
public InnerClass addInnerClass(String name, Class type, Class owner) {
String typeName = (type == null) ? null : type.getName();
String ownerName = (owner == null) ? null : owner.getName();
return addInnerClass(name, typeName, ownerName);
}
/**
* Add an inner class.
*
* @param name the simple name of the class, or null if anonymous
* @param type the class of the inner class
* @param owner the declaring class, or null if not a member class
*/
public InnerClass addInnerClass(String name, BCClass type, BCClass owner) {
String typeName = (type == null) ? null : type.getName();
String ownerName = (owner == null) ? null : owner.getName();
return addInnerClass(name, typeName, ownerName);
}
/**
* Clear all inner classes from this entity.
*/
public void clear() {
InnerClass inner;
for (Iterator itr = _innerClasses.iterator(); itr.hasNext();) {
inner = (InnerClass) itr.next();
itr.remove();
inner.invalidate();
}
}
/**
* Remove the inner class with the given name. Use null for anonymous
* classes.
*
* @return true if an inner class was removed, false otherwise
*/
public boolean removeInnerClass(String name) {
return removeInnerClass(getInnerClass(name));
}
/**
* Remove the given inner class. After being removed, the given inner
* class is invalid, and the result of any operations on it are undefined.
*
* @return true if the inner class was removed, false otherwise
*/
public boolean removeInnerClass(InnerClass innerClass) {
if (innerClass == null || !_innerClasses.remove(innerClass))
return false;
innerClass.invalidate();
return true;
}
public void acceptVisit(BCVisitor visit) {
visit.enterInnerClasses(this);
InnerClass[] inners = getInnerClasses();
for (int i = 0; i < inners.length; i++)
inners[i].acceptVisit(visit);
visit.exitInnerClasses(this);
}
int getLength() {
return 2 + (8 * _innerClasses.size());
}
void read(Attribute other) {
setInnerClasses(((InnerClasses) other).getInnerClasses());
}
void read(DataInput in, int length) throws IOException {
clear();
int numInnerClasses = in.readUnsignedShort();
InnerClass innerClass;
for (int i = 0; i < numInnerClasses; i++) {
innerClass = addInnerClass();
innerClass.read(in);
}
}
void write(DataOutput out, int length) throws IOException {
InnerClass[] inners = getInnerClasses();
out.writeShort(inners.length);
for (int i = 0; i < inners.length; i++)
inners[i].write(out);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy