in packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/CallbackExtensions.cs [71:147]
private static CallbackResult? InvokeMethod(InvokeRequest request, IReferenceMap referenceMap)
{
request = request ?? throw new ArgumentNullException(nameof(request));
var deputy = referenceMap.GetOrCreateNativeReference(request.ObjectReference);
var methodInfo = ReflectionUtils.GetNativeMethod(deputy.GetType(), request.Method);
if (methodInfo == null)
{
throw new InvalidOperationException(
$"Received callback for {deputy.GetType().Name}.{request.Method} method, but this method does not exist");
}
var attribute = methodInfo.GetAttribute<JsiiMethodAttribute>()!;
var parameters = methodInfo.GetParameters();
var converter = ServiceContainer.ServiceProvider.GetRequiredService<IJsiiToFrameworkConverter>();
var rehydratedArgs = Enumerable.Range(0, request.Arguments?.Length ?? 0)
.Select(n =>
{
var paramIndex = n >= parameters.Length ? parameters.Length - 1 : n;
var requiredType = parameters[paramIndex].ParameterType;
if (!converter.TryConvert(attribute.Parameters[paramIndex], requiredType, referenceMap,
request.Arguments![n], out var value))
{
throw new JsiiError($"Unable to convert {request.Arguments![n]} to {requiredType.Name}");
}
if (attribute.Parameters[paramIndex].IsVariadic)
{
var array = Array.CreateInstance(value?.GetType() ?? requiredType, 1);
array.SetValue(value, 0);
value = array;
}
if (!requiredType.IsInstanceOfType(value) && value is IConvertible)
{
value = Convert.ChangeType(value, requiredType, CultureInfo.InvariantCulture);
}
return value;
}).ToArray();
var invokeParameters = Enumerable.Range(0, parameters.Length)
.Select(n =>
{
if (n >= rehydratedArgs.Length)
{
return null;
}
if (n == parameters.Length - 1 && rehydratedArgs.Length > parameters.Length)
{
var allArgs = rehydratedArgs.TakeLast(rehydratedArgs.Length - parameters.Length + 1);
var array = Array.CreateInstance(
parameters[parameters.Length - 1].ParameterType.GetElementType()!,
allArgs.Select(list => (list as Array)!.Length).Sum());
var idx = 0;
foreach (var list in allArgs)
{
foreach (var item in (list as Array)!)
{
array.SetValue(item, idx);
idx += 1;
}
}
return array;
}
return rehydratedArgs[n];
}).ToArray();
var returnValue = methodInfo.Invoke(deputy, invokeParameters);
return attribute?.Returns != null ? new CallbackResult(attribute.Returns, returnValue) : null;
}