/// <summary>
/// Creates a <see cref="CatchBlock"/> representing a catch statement with the specified elements.
/// </summary>
/// <param name="type">The <see cref="Type"/> of <see cref="Exception"/> this <see cref="CatchBlock"/> will handle.</param>
/// <param name="variable">A <see cref="ParameterExpression"/> representing a reference to the <see cref="Exception"/> object caught by this handler.</param>
/// <param name="body">The body of the catch statement.</param>
/// <param name="filter">The body of the <see cref="Exception"/> filter.</param>
/// <returns>The created <see cref="CatchBlock"/>.</returns>
/// <remarks><paramref name="type"/> must be non-null and match the type of <paramref name="variable"/> (if it is supplied).</remarks>
public static CatchBlock MakeCatchBlock(Type type, ParameterExpression variable, Expression body, Expression filter)
{
ContractUtils.RequiresNotNull(type, nameof(type));
ContractUtils.Requires(variable == null || TypeUtils.AreEquivalent(variable.Type, type), nameof(variable));
if (variable == null)
{
TypeUtils.ValidateType(type, nameof(type));
if (type.IsByRef)
{
throw Error.TypeMustNotBeByRef(nameof(type));
}
if (type.IsPointer)
{
throw Error.TypeMustNotBePointer(nameof(type));
}
}
else if (variable.IsByRef)
{
throw Error.VariableMustNotBeByRef(variable, variable.Type, nameof(variable));
}
ExpressionUtils.RequiresCanRead(body, nameof(body));
if (filter != null)
{
ExpressionUtils.RequiresCanRead(filter, nameof(filter));
if (filter.Type != typeof(bool))
{
throw Error.ArgumentMustBeBoolean(nameof(filter));
}
}
return(new CatchBlock(type, variable, body, filter));
}