package org.jf.baksmali.Adaptors;
import org.jf.baksmali.Adaptors.EncodedValue.EncodedValueAdaptor;
import org.jf.dexlib2.MethodHandleType;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.iface.reference.*;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.util.ReferenceUtil;
import org.jf.util.IndentingWriter;
import org.jf.util.StringUtils;
import java.io.IOException;
public class ReferenceFormatter {
public static void writeStringReference(IndentingWriter writer, String item) throws IOException {
writer.write('"');
StringUtils.writeEscapedString(writer, item);
writer.write('"');
}
public static void writeCallSiteReference(IndentingWriter writer, CallSiteReference callSite) throws IOException {
writer.write(callSite.getName());
writer.write('(');
writer.write('"');
StringUtils.writeEscapedString(writer, callSite.getMethodName());
writer.write("\", ");
writeReference(writer, ReferenceType.METHOD_PROTO, callSite.getMethodProto());
for (EncodedValue encodedValue : callSite.getExtraArguments()) {
writer.write(", ");
EncodedValueAdaptor.writeTo(writer, encodedValue, null);
}
writer.write(")@");
MethodHandleReference methodHandle = callSite.getMethodHandle();
if (methodHandle.getMethodHandleType() != MethodHandleType.INVOKE_STATIC) {
throw new IllegalArgumentException("The linker method handle for a call site must be of type invoke-static");
}
writeReference(writer, ReferenceType.METHOD, callSite.getMethodHandle().getMemberReference());
}
public static void writeReference(IndentingWriter writer, int referenceType,
Reference reference) throws IOException {
switch (referenceType) {
case ReferenceType.STRING:
writeStringReference(writer, ((StringReference)reference).getString());
return;
case ReferenceType.TYPE:
writer.write(((TypeReference)reference).getType());
return;
case ReferenceType.METHOD:
ReferenceUtil.writeMethodDescriptor(writer, (MethodReference)reference);
return;
case ReferenceType.FIELD:
ReferenceUtil.writeFieldDescriptor(writer, (FieldReference)reference);
return;
case ReferenceType.METHOD_PROTO:
ReferenceUtil.writeMethodProtoDescriptor(writer, (MethodProtoReference)reference);
return;
case ReferenceType.METHOD_HANDLE:
ReferenceUtil.writeMethodHandle(writer, (MethodHandleReference)reference);
return;
case ReferenceType.CALL_SITE:
writeCallSiteReference(writer, (CallSiteReference)reference);
return;
default:
throw new IllegalStateException("Unknown reference type");
}
}
}