in log4j-weaver/src/main/java/org/apache/logging/log4j/weaver/log4j2/LoggerConversionHandler.java [160:211]
private void handleLogMethods(LocationMethodVisitor mv, String name, String descriptor) {
final Type[] types = Type.getArgumentTypes(descriptor);
final int[] varIndexes = new int[types.length];
int from = types.length > 0 && types[0].equals(LEVEL_TYPE) ? 1 : 0;
int to = types.length;
// Store arguments to local variables
// TODO: most of the time there is a more efficient way
for (int i = to - 1; i >= from; i--) {
varIndexes[i] = mv.nextLocal();
mv.storeLocal(varIndexes[i], types[i]);
}
// create the LogBuilder
createLogBuilder(mv, name);
mv.storeLocation();
// Marker argument
if (from < to && types[from].equals(MARKER_TYPE)) {
mv.loadLocal(varIndexes[from], MARKER_TYPE);
mv.invokeInterface(LOG_BUILDER_TYPE, WITH_MARKER_METHOD);
from++;
}
// Throwable argument
if (from < to && types[to - 1].equals(THROWABLE_TYPE)) {
mv.loadLocal(varIndexes[to - 1], THROWABLE_TYPE);
mv.invokeInterface(LOG_BUILDER_TYPE, WITH_THROWABLE_METHOD);
to--;
}
// Call log(...)
final Type[] arguments;
// We need to replace (Supplier<?>) with ("{}", Supplier<?>)
if (SUPPLIER_TYPE.equals(types[from])) {
mv.push("{}");
mv.push(1);
mv.newArray(SUPPLIER_TYPE);
mv.dup();
mv.push(0);
mv.loadLocal(varIndexes[from], types[from]);
mv.arrayStore(SUPPLIER_TYPE);
arguments = LOG_BUILDER_LOG_STRING_SUPPLIER;
// We need to convert MessageSupplier to Supplier<Message>
} else if (MESSAGE_SUPPLIER_TYPE.equals(types[from])) {
mv.loadLocal(varIndexes[from], types[from]);
mv.invokeSupplierLambda(SupplierLambdaType.MESSAGE_SUPPLIER);
arguments = LOG_BUILDER_LOG_SUPPLIER_MESSAGE;
} else {
for (int i = from; i < to; i++) {
mv.loadLocal(varIndexes[i], types[i]);
}
arguments = Arrays.copyOfRange(types, from, to);
}
final Method logMethod = new Method("log", Type.VOID_TYPE, arguments);
mv.invokeInterface(LOG_BUILDER_TYPE, logMethod);
}