serp.bytecode.Attribute Maven / Gradle / Ivy
package serp.bytecode;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import serp.bytecode.lowlevel.*;
import serp.bytecode.visitor.*;
import serp.util.*;
/**
* In bytecode attributes are used to represent anything that is not
* part of the class structure. This includes the source file name, code of
* methods, the line number table, etc. All attributes contain at a minimum
* an immutable name that also determines the attribute's type.
*
* @author Abe White
*/
public abstract class Attribute extends Attributes implements VisitAcceptor {
private int _nameIndex = 0;
private Attributes _owner = null;
Attribute(int nameIndex, Attributes owner) {
_owner = owner;
_nameIndex = nameIndex;
}
/**
* Create an attribute of the appropriate type based on the
* the attribute name.
*/
static Attribute create(String name, Attributes owner) {
// special case for annotations
int nameIndex = owner.getPool().findUTF8Entry(name, true);
if ("RuntimeVisibleAnnotations".equals(name)
|| "RuntimeInvisibleAnnotations".equals(name))
return new Annotations(nameIndex, owner);
try {
Class type = Class.forName("serp.bytecode." + name);
Constructor cons = type.getDeclaredConstructor(new Class[] {
int.class, Attributes.class
});
return (Attribute) cons.newInstance(new Object[] {
Numbers.valueOf(nameIndex), owner
});
} catch (Throwable t) {
return new UnknownAttribute(nameIndex, owner);
}
}
/**
* Return the {@link Attributes} that owns this attribute. The entity
* might be a {@link BCClass}, {@link BCField}, {@link BCMethod}, or other
* attribute.
*/
public Attributes getOwner() {
return _owner;
}
/**
* Return the index in the {@link ConstantPool} of the {@link UTF8Entry}
* holding the name of this attribute.
*/
public int getNameIndex() {
return _nameIndex;
}
/**
* Return the name of this attribute.
*/
public String getName() {
return ((UTF8Entry) getPool().getEntry(_nameIndex)).getValue();
}
public Project getProject() {
return _owner.getProject();
}
public ConstantPool getPool() {
return _owner.getPool();
}
public ClassLoader getClassLoader() {
return _owner.getClassLoader();
}
public boolean isValid() {
return _owner != null;
}
Collection getAttributesHolder() {
return Collections.EMPTY_LIST;
}
/**
* Invalidate this attribute.
*/
void invalidate() {
_owner = null;
}
/**
* Return the length of the bytecode representation of this attribute
* in bytes, excluding the name index.
*/
int getLength() {
return 0;
}
/**
* Copy the information from the given attribute to this one. Does
* nothing by default.
*/
void read(Attribute other) {
}
/**
* Read the attribute bytecode from the given stream, up to length
* bytes, excluding the name index. Does nothing by default.
*/
void read(DataInput in, int length) throws IOException {
}
/**
* Write the attribute bytecode to the given stream, up to length bytes,
* excluding the name index. Does nothing by default.
*/
void write(DataOutput out, int length) throws IOException {
}
}