void DefineAsyncMethods(TypeExpression returnType)
{
var iasync_result = Module.PredefinedTypes.IAsyncResult;
var async_callback = Module.PredefinedTypes.AsyncCallback;
//
// It's ok when async types don't exist, the delegate will have Invoke method only
//
if (!iasync_result.Define() || !async_callback.Define())
{
return;
}
//
// BeginInvoke
//
ParametersCompiled async_parameters;
if (Parameters.Count == 0)
{
async_parameters = ParametersCompiled.EmptyReadOnlyParameters;
}
else
{
var compiled = new Parameter[Parameters.Count];
for (int i = 0; i < compiled.Length; ++i)
{
var p = parameters[i];
compiled[i] = new Parameter(new TypeExpression(parameters.Types[i], Location),
p.Name,
p.ModFlags & Parameter.Modifier.RefOutMask,
p.OptAttributes == null ? null : p.OptAttributes.Clone(), Location);
}
async_parameters = new ParametersCompiled(compiled);
}
async_parameters = ParametersCompiled.MergeGenerated(Compiler, async_parameters, false,
new Parameter[] {
new Parameter(new TypeExpression(async_callback.TypeSpec, Location), "callback", Parameter.Modifier.NONE, null, Location),
new Parameter(new TypeExpression(Compiler.BuiltinTypes.Object, Location), "object", Parameter.Modifier.NONE, null, Location)
},
new [] {
async_callback.TypeSpec,
Compiler.BuiltinTypes.Object
}
);
BeginInvokeBuilder = new Method(this,
new TypeExpression(iasync_result.TypeSpec, Location), MethodModifiers,
new MemberName("BeginInvoke"), async_parameters, null);
BeginInvokeBuilder.Define();
//
// EndInvoke is a bit more interesting, all the parameters labeled as
// out or ref have to be duplicated here.
//
//
// Define parameters, and count out/ref parameters
//
ParametersCompiled end_parameters;
int out_params = 0;
foreach (Parameter p in Parameters.FixedParameters)
{
if ((p.ModFlags & Parameter.Modifier.RefOutMask) != 0)
{
++out_params;
}
}
if (out_params > 0)
{
Parameter[] end_params = new Parameter[out_params];
int param = 0;
for (int i = 0; i < Parameters.FixedParameters.Length; ++i)
{
Parameter p = parameters [i];
if ((p.ModFlags & Parameter.Modifier.RefOutMask) == 0)
{
continue;
}
end_params [param++] = new Parameter(new TypeExpression(p.Type, Location),
p.Name,
p.ModFlags & Parameter.Modifier.RefOutMask,
p.OptAttributes == null ? null : p.OptAttributes.Clone(), Location);
}
end_parameters = new ParametersCompiled(end_params);
}
else
{
end_parameters = ParametersCompiled.EmptyReadOnlyParameters;
}
end_parameters = ParametersCompiled.MergeGenerated(Compiler, end_parameters, false,
new Parameter(
new TypeExpression(iasync_result.TypeSpec, Location),
"result", Parameter.Modifier.NONE, null, Location),
iasync_result.TypeSpec);
//
// Create method, define parameters, register parameters with type system
//
EndInvokeBuilder = new Method(this, returnType, MethodModifiers, new MemberName("EndInvoke"), end_parameters, null);
EndInvokeBuilder.Define();
}