private void processMethod(Method method, DirectClassFile cf, Element classElement, Map<String, ReferenceKind> referencedTypes, boolean skeletonOnly)
{
final boolean localInfo= true;
final int positionInfo= PositionList.LINES;
CstMethodRef meth= new CstMethodRef(method.getDefiningClass(), method.getNat());
// Extract flags for this method.
int accessFlags= method.getAccessFlags();
boolean isNative= AccessFlags.isNative(accessFlags);
boolean isStatic= AccessFlags.isStatic(accessFlags);
boolean isAbstract= AccessFlags.isAbstract(accessFlags);
// Create XMLVM element for this method
Element methodElement= new Element("method", NS_XMLVM);
methodElement.setAttribute("name", method.getName().getString());
methodElement.setAttribute("signature", method.getNat().getDescriptor().toHuman());// meth.getPrototype().getDescriptor());
classElement.addContent(methodElement);
// Set the access flag attributes for this method.
processAccessFlags(accessFlags, methodElement);
// Create signature element.
methodElement.addContent(processSignature(meth, referencedTypes));
// Create code element.
Element codeElement= new Element("code", NS_DEX);
methodElement.addContent(codeElement);
// Add delegate method information
addDelegateElement(method, methodElement);
// For skeleton-only classes we don't generate instructions.
if (skeletonOnly)
{
methodElement.setAttribute("noImplementation", "true");
return;
}
// Native and abstract methods don't have an implementation.
if (isNative || isAbstract)
{
return;
}
ConcreteMethod concrete= new ConcreteMethod(method, cf, (positionInfo != PositionList.NONE), localInfo);
TranslationAdvice advice= DexTranslationAdvice.THE_ONE;
RopMethod rmeth= Ropper.convert(concrete, advice);
int paramSize= meth.getParameterWordCount(isStatic);
String canonicalName= method.getDefiningClass().getClassType().getDescriptor() + "." + method.getName().getString();
if (LOTS_OF_DEBUG)
{
System.out.println("\n\nMethod: " + canonicalName);
}
// Optimize
rmeth= Optimizer.optimize(rmeth, paramSize, isStatic, localInfo, advice);
LocalVariableInfo locals= null;
if (localInfo)
{
locals= LocalVariableExtractor.extract(rmeth);
}
DalvCode code= RopTranslator.translate(rmeth, positionInfo, locals, paramSize);
DalvCode.AssignIndicesCallback callback= new DalvCode.AssignIndicesCallback()
{
public int getIndex(Constant cst)
{
// Everything is at index 0!
return 0;
}
};
code.assignIndices(callback);
DalvInsnList instructions= code.getInsns();
codeElement.setAttribute("register-size", String.valueOf(instructions.getRegistersSize()));
processLocals(instructions.getRegistersSize(), isStatic, parseClassName(cf.getThisClass().getClassType().getClassName()).toString(), meth.getPrototype().getParameterTypes(), codeElement);
Map<Integer, SwitchData> switchDataBlocks= extractSwitchData(instructions);
Map<Integer, ArrayData> arrayData= extractArrayData(instructions);
CatchTable catches= code.getCatches();
processCatchTable(catches, codeElement);
Map<Integer, Target> targets= extractTargets(instructions, catches);