1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
5 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
6 * copy of the license can be found in the License.html file at the root of this distribution. If
7 * you cannot locate the Apache License, Version 2.0, please send an email to
8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
9 * by the terms of the Apache License, Version 2.0.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
17 using System
.Diagnostics
;
18 using System
.Dynamic
.Utils
;
21 namespace Microsoft
.Scripting
.Ast
{
23 namespace System
.Linq
.Expressions
{
27 /// Represents a catch statement in a try block.
28 /// 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.
30 [DebuggerTypeProxy(typeof(Expression
.CatchBlockProxy
))]
31 public sealed class CatchBlock
{
32 private readonly Type _test
;
33 private readonly ParameterExpression _var
;
34 private readonly Expression _body
;
35 private readonly Expression _filter
;
37 internal CatchBlock(Type test
, ParameterExpression variable
, Expression body
, Expression filter
) {
45 /// Gets a reference to the <see cref="Exception"/> object caught by this handler.
47 public ParameterExpression Variable
{
52 /// Gets the type of <see cref="Exception"/> this handler catches.
59 /// Gets the body of the catch block.
61 public Expression Body
{
66 /// Gets the body of the <see cref="CatchBlock"/>'s filter.
68 public Expression Filter
{
75 /// Returns a <see cref="String"/> that represents the current <see cref="Object"/>.
77 /// <returns>A <see cref="String"/> that represents the current <see cref="Object"/>. </returns>
78 public override string ToString() {
79 return ExpressionStringBuilder
.CatchBlockToString(this);
83 /// Creates a new expression that is like this one, but using the
84 /// supplied children. If all of the children are the same, it will
85 /// return this expression.
87 /// <param name="variable">The <see cref="Variable" /> property of the result.</param>
88 /// <param name="filter">The <see cref="Filter" /> property of the result.</param>
89 /// <param name="body">The <see cref="Body" /> property of the result.</param>
90 /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
91 public CatchBlock
Update(ParameterExpression variable
, Expression filter
, Expression body
) {
92 if (variable
== Variable
&& filter
== Filter
&& body
== Body
) {
95 return Expression
.MakeCatchBlock(Test
, variable
, body
, filter
);
99 public partial class Expression
{
101 /// Creates a <see cref="CatchBlock"/> representing a catch statement.
102 /// The <see cref="Type"/> of object to be caught can be specified but no reference to the object
103 /// will be available for use in the <see cref="CatchBlock"/>.
105 /// <param name="type">The <see cref="Type"/> of <see cref="Exception"/> this <see cref="CatchBlock"/> will handle.</param>
106 /// <param name="body">The body of the catch statement.</param>
107 /// <returns>The created <see cref="CatchBlock"/>.</returns>
108 public static CatchBlock
Catch(Type type
, Expression body
) {
109 return MakeCatchBlock(type
, null, body
, null);
113 /// Creates a <see cref="CatchBlock"/> representing a catch statement with a reference to the caught object for use in the handler body.
115 /// <param name="variable">A <see cref="ParameterExpression"/> representing a reference to the <see cref="Exception"/> object caught by this handler.</param>
116 /// <param name="body">The body of the catch statement.</param>
117 /// <returns>The created <see cref="CatchBlock"/>.</returns>
118 public static CatchBlock
Catch(ParameterExpression variable
, Expression body
) {
119 ContractUtils
.RequiresNotNull(variable
, "variable");
120 return MakeCatchBlock(variable
.Type
, variable
, body
, null);
124 /// Creates a <see cref="CatchBlock"/> representing a catch statement with
125 /// an <see cref="Exception"/> filter but no reference to the caught <see cref="Exception"/> object.
127 /// <param name="type">The <see cref="Type"/> of <see cref="Exception"/> this <see cref="CatchBlock"/> will handle.</param>
128 /// <param name="body">The body of the catch statement.</param>
129 /// <param name="filter">The body of the <see cref="Exception"/> filter.</param>
130 /// <returns>The created <see cref="CatchBlock"/>.</returns>
131 public static CatchBlock
Catch(Type type
, Expression body
, Expression filter
) {
132 return MakeCatchBlock(type
, null, body
, filter
);
136 /// Creates a <see cref="CatchBlock"/> representing a catch statement with
137 /// an <see cref="Exception"/> filter and a reference to the caught <see cref="Exception"/> object.
139 /// <param name="variable">A <see cref="ParameterExpression"/> representing a reference to the <see cref="Exception"/> object caught by this handler.</param>
140 /// <param name="body">The body of the catch statement.</param>
141 /// <param name="filter">The body of the <see cref="Exception"/> filter.</param>
142 /// <returns>The created <see cref="CatchBlock"/>.</returns>
143 public static CatchBlock
Catch(ParameterExpression variable
, Expression body
, Expression filter
) {
144 ContractUtils
.RequiresNotNull(variable
, "variable");
145 return MakeCatchBlock(variable
.Type
, variable
, body
, filter
);
149 /// Creates a <see cref="CatchBlock"/> representing a catch statement with the specified elements.
151 /// <param name="type">The <see cref="Type"/> of <see cref="Exception"/> this <see cref="CatchBlock"/> will handle.</param>
152 /// <param name="variable">A <see cref="ParameterExpression"/> representing a reference to the <see cref="Exception"/> object caught by this handler.</param>
153 /// <param name="body">The body of the catch statement.</param>
154 /// <param name="filter">The body of the <see cref="Exception"/> filter.</param>
155 /// <returns>The created <see cref="CatchBlock"/>.</returns>
156 /// <remarks><paramref name="type"/> must be non-null and match the type of <paramref name="variable"/> (if it is supplied).</remarks>
157 public static CatchBlock
MakeCatchBlock(Type type
, ParameterExpression variable
, Expression body
, Expression filter
) {
158 ContractUtils
.RequiresNotNull(type
, "type");
159 ContractUtils
.Requires(variable
== null || TypeUtils
.AreEquivalent(variable
.Type
, type
), "variable");
160 if (variable
!= null && variable
.IsByRef
) {
161 throw Error
.VariableMustNotBeByRef(variable
, variable
.Type
);
163 RequiresCanRead(body
, "body");
164 if (filter
!= null) {
165 RequiresCanRead(filter
, "filter");
166 if (filter
.Type
!= typeof(bool)) throw Error
.ArgumentMustBeBoolean();
169 return new CatchBlock(type
, variable
, body
, filter
);