You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
7.8 KiB
177 lines
7.8 KiB
#if NET20 || NET30 || !NET_4_6 |
|
|
|
// Copyright (c) Microsoft. All rights reserved. |
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information. |
|
|
|
using System.Diagnostics; |
|
using System.Dynamic.Utils; |
|
|
|
namespace System.Linq.Expressions.Reimplement |
|
{ |
|
/// <summary> |
|
/// Represents a catch statement in a try block. |
|
/// This must have the same return type (i.e., the type of <see cref="P:CatchBlock.Body"/>) as the try block it is associated with. |
|
/// </summary> |
|
[DebuggerTypeProxy(typeof(CatchBlockProxy))] |
|
public sealed class CatchBlock |
|
{ |
|
private readonly Type _test; |
|
private readonly ParameterExpression _var; |
|
private readonly Expression _body; |
|
private readonly Expression _filter; |
|
|
|
internal CatchBlock(Type test, ParameterExpression variable, Expression body, Expression filter) |
|
{ |
|
_test = test; |
|
_var = variable; |
|
_body = body; |
|
_filter = filter; |
|
} |
|
|
|
/// <summary> |
|
/// Gets a reference to the <see cref="Exception"/> object caught by this handler. |
|
/// </summary> |
|
public ParameterExpression Variable |
|
{ |
|
get { return _var; } |
|
} |
|
|
|
/// <summary> |
|
/// Gets the type of <see cref="Exception"/> this handler catches. |
|
/// </summary> |
|
public Type Test |
|
{ |
|
get { return _test; } |
|
} |
|
|
|
/// <summary> |
|
/// Gets the body of the catch block. |
|
/// </summary> |
|
public Expression Body |
|
{ |
|
get { return _body; } |
|
} |
|
|
|
/// <summary> |
|
/// Gets the body of the <see cref="CatchBlock"/>'s filter. |
|
/// </summary> |
|
public Expression Filter |
|
{ |
|
get { return _filter; } |
|
} |
|
|
|
/// <summary> |
|
/// Returns a <see cref="string"/> that represents the current <see cref="object"/>. |
|
/// </summary> |
|
/// <returns>A <see cref="string"/> that represents the current <see cref="object"/>. </returns> |
|
public override string ToString() |
|
{ |
|
return ExpressionStringBuilder.CatchBlockToString(this); |
|
} |
|
|
|
/// <summary> |
|
/// Creates a new expression that is like this one, but using the |
|
/// supplied children. If all of the children are the same, it will |
|
/// return this expression. |
|
/// </summary> |
|
/// <param name="variable">The <see cref="Variable" /> property of the result.</param> |
|
/// <param name="filter">The <see cref="Filter" /> property of the result.</param> |
|
/// <param name="body">The <see cref="Body" /> property of the result.</param> |
|
/// <returns>This expression if no children changed, or an expression with the updated children.</returns> |
|
public CatchBlock Update(ParameterExpression variable, Expression filter, Expression body) |
|
{ |
|
if (variable == Variable && filter == Filter && body == Body) |
|
{ |
|
return this; |
|
} |
|
return Expression.MakeCatchBlock(Test, variable, body, filter); |
|
} |
|
} |
|
|
|
public partial class Expression |
|
{ |
|
/// <summary> |
|
/// Creates a <see cref="CatchBlock"/> representing a catch statement. |
|
/// The <see cref="Type"/> of object to be caught can be specified but no reference to the object |
|
/// will be available for use in the <see cref="CatchBlock"/>. |
|
/// </summary> |
|
/// <param name="type">The <see cref="Type"/> of <see cref="Exception"/> this <see cref="CatchBlock"/> will handle.</param> |
|
/// <param name="body">The body of the catch statement.</param> |
|
/// <returns>The created <see cref="CatchBlock"/>.</returns> |
|
public static CatchBlock Catch(Type type, Expression body) |
|
{ |
|
return MakeCatchBlock(type, null, body, null); |
|
} |
|
|
|
/// <summary> |
|
/// Creates a <see cref="CatchBlock"/> representing a catch statement with a reference to the caught object for use in the handler body. |
|
/// </summary> |
|
/// <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> |
|
/// <returns>The created <see cref="CatchBlock"/>.</returns> |
|
public static CatchBlock Catch(ParameterExpression variable, Expression body) |
|
{ |
|
ContractUtils.RequiresNotNull(variable, "variable"); |
|
return MakeCatchBlock(variable.Type, variable, body, null); |
|
} |
|
|
|
/// <summary> |
|
/// Creates a <see cref="CatchBlock"/> representing a catch statement with |
|
/// an <see cref="Exception"/> filter but no reference to the caught <see cref="Exception"/> object. |
|
/// </summary> |
|
/// <param name="type">The <see cref="Type"/> of <see cref="Exception"/> this <see cref="CatchBlock"/> will handle.</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> |
|
public static CatchBlock Catch(Type type, Expression body, Expression filter) |
|
{ |
|
return MakeCatchBlock(type, null, body, filter); |
|
} |
|
|
|
/// <summary> |
|
/// Creates a <see cref="CatchBlock"/> representing a catch statement with |
|
/// an <see cref="Exception"/> filter and a reference to the caught <see cref="Exception"/> object. |
|
/// </summary> |
|
/// <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> |
|
public static CatchBlock Catch(ParameterExpression variable, Expression body, Expression filter) |
|
{ |
|
ContractUtils.RequiresNotNull(variable, "variable"); |
|
return MakeCatchBlock(variable.Type, variable, body, filter); |
|
} |
|
|
|
/// <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, "type"); |
|
ContractUtils.Requires(variable == null || variable.Type == type, "variable"); |
|
if (variable != null && variable.IsByRef) |
|
{ |
|
throw Error.VariableMustNotBeByRef(variable, variable.Type); |
|
} |
|
RequiresCanRead(body, "body"); |
|
if (filter != null) |
|
{ |
|
RequiresCanRead(filter, "filter"); |
|
if (filter.Type != typeof(bool)) |
|
{ |
|
throw Error.ArgumentMustBeBoolean(); |
|
} |
|
} |
|
|
|
return new CatchBlock(type, variable, body, filter); |
|
} |
|
} |
|
} |
|
|
|
#endif |