MemberListParserpublic abstract class MemberListParser extends Object Parser for lists of class file members (that is, fields and methods). |
Fields Summary |
---|
private final DirectClassFile | cf{@code non-null;} the class file to parse from | private final com.android.dx.rop.cst.CstType | definer{@code non-null;} class being defined | private final int | offsetoffset in the byte array of the classfile to the start of the list | private final AttributeFactory | attributeFactory{@code non-null;} attribute factory to use | private int | endOffset{@code >= -1;} the end offset of this list in the byte array of the
classfile, or {@code -1} if not yet parsed | private com.android.dx.cf.iface.ParseObserver | observer{@code null-ok;} parse observer, if any |
Constructors Summary |
---|
public MemberListParser(DirectClassFile cf, com.android.dx.rop.cst.CstType definer, int offset, AttributeFactory attributeFactory)Constructs an instance.
if (cf == null) {
throw new NullPointerException("cf == null");
}
if (offset < 0) {
throw new IllegalArgumentException("offset < 0");
}
if (attributeFactory == null) {
throw new NullPointerException("attributeFactory == null");
}
this.cf = cf;
this.definer = definer;
this.offset = offset;
this.attributeFactory = attributeFactory;
this.endOffset = -1;
|
Methods Summary |
---|
protected abstract int | getAttributeContext()Gets the {@code CTX_*} constant to use when parsing attributes.
Subclasses must override this method.
| protected final int | getCount()Gets the count of elements in the list.
ByteArray bytes = cf.getBytes();
return bytes.getUnsignedShort(offset);
| protected final com.android.dx.rop.cst.CstType | getDefiner()Gets the class file being defined.
return definer;
| public int | getEndOffset()Gets the end offset of this constant pool in the {@code byte[]}
which it came from.
parseIfNecessary();
return endOffset;
| protected abstract java.lang.String | humanAccessFlags(int accessFlags)Gets the human-oriented string for the given access flags.
Subclasses must override this method.
| protected abstract java.lang.String | humanName()Gets the human-oriented name for what this instance is parsing.
Subclasses must override this method.
| private void | parse()Does the actual parsing.
int attributeContext = getAttributeContext();
int count = getCount();
int at = offset + 2; // Skip the count.
ByteArray bytes = cf.getBytes();
ConstantPool pool = cf.getConstantPool();
if (observer != null) {
observer.parsed(bytes, offset, 2,
humanName() + "s_count: " + Hex.u2(count));
}
for (int i = 0; i < count; i++) {
try {
int accessFlags = bytes.getUnsignedShort(at);
int nameIdx = bytes.getUnsignedShort(at + 2);
int descIdx = bytes.getUnsignedShort(at + 4);
CstString name = (CstString) pool.get(nameIdx);
CstString desc = (CstString) pool.get(descIdx);
if (observer != null) {
observer.startParsingMember(bytes, at, name.getString(),
desc.getString());
observer.parsed(bytes, at, 0, "\n" + humanName() +
"s[" + i + "]:\n");
observer.changeIndent(1);
observer.parsed(bytes, at, 2,
"access_flags: " +
humanAccessFlags(accessFlags));
observer.parsed(bytes, at + 2, 2,
"name: " + name.toHuman());
observer.parsed(bytes, at + 4, 2,
"descriptor: " + desc.toHuman());
}
at += 6;
AttributeListParser parser =
new AttributeListParser(cf, attributeContext, at,
attributeFactory);
parser.setObserver(observer);
at = parser.getEndOffset();
StdAttributeList attributes = parser.getList();
attributes.setImmutable();
CstNat nat = new CstNat(name, desc);
Member member = set(i, accessFlags, nat, attributes);
if (observer != null) {
observer.changeIndent(-1);
observer.parsed(bytes, at, 0, "end " + humanName() +
"s[" + i + "]\n");
observer.endParsingMember(bytes, at, name.getString(),
desc.getString(), member);
}
} catch (ParseException ex) {
ex.addContext("...while parsing " + humanName() + "s[" + i +
"]");
throw ex;
} catch (RuntimeException ex) {
ParseException pe = new ParseException(ex);
pe.addContext("...while parsing " + humanName() + "s[" + i +
"]");
throw pe;
}
}
endOffset = at;
| protected final void | parseIfNecessary()Runs {@link #parse} if it has not yet been run successfully.
if (endOffset < 0) {
parse();
}
| protected abstract com.android.dx.cf.iface.Member | set(int n, int accessFlags, com.android.dx.rop.cst.CstNat nat, com.android.dx.cf.iface.AttributeList attributes)Sets an element in the list. Subclasses must override this method.
| public final void | setObserver(com.android.dx.cf.iface.ParseObserver observer)Sets the parse observer for this instance.
this.observer = observer;
|
|