Merge pull request #439 from mono-soc-2012/garyb/iconfix
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Scripting.Core / Ast / CatchBlock.cs
1 /* ****************************************************************************
2  *
3  * Copyright (c) Microsoft Corporation. 
4  *
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.
10  *
11  * You must not remove this notice, or any other, from this software.
12  *
13  *
14  * ***************************************************************************/
15
16 using System;
17 using System.Diagnostics;
18 using System.Dynamic.Utils;
19
20 #if !FEATURE_CORE_DLR
21 namespace Microsoft.Scripting.Ast {
22 #else
23 namespace System.Linq.Expressions {
24 #endif
25
26     /// <summary>
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.
29     /// </summary>
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;
36
37         internal CatchBlock(Type test, ParameterExpression variable, Expression body, Expression filter) {
38             _test = test;
39             _var = variable;
40             _body = body;
41             _filter = filter;
42         }
43
44         /// <summary>
45         /// Gets a reference to the <see cref="Exception"/> object caught by this handler.
46         /// </summary>
47         public ParameterExpression Variable {
48             get { return _var; }
49         }
50
51         /// <summary>
52         /// Gets the type of <see cref="Exception"/> this handler catches.
53         /// </summary>
54         public Type Test {
55             get { return _test; }
56         }
57
58         /// <summary>
59         /// Gets the body of the catch block.
60         /// </summary>
61         public Expression Body {
62             get { return _body; }
63         }
64
65         /// <summary>
66         /// Gets the body of the <see cref="CatchBlock"/>'s filter.
67         /// </summary>
68         public Expression Filter {
69             get {
70                 return _filter;
71             }
72         }
73
74         /// <summary>
75         /// Returns a <see cref="String"/> that represents the current <see cref="Object"/>. 
76         /// </summary>
77         /// <returns>A <see cref="String"/> that represents the current <see cref="Object"/>. </returns>
78         public override string ToString() {
79             return ExpressionStringBuilder.CatchBlockToString(this);
80         }
81
82         /// <summary>
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.
86         /// </summary>
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) {
93                 return this;
94             }
95             return Expression.MakeCatchBlock(Test, variable, body, filter);
96         }
97     }
98
99     public partial class Expression {
100         /// <summary>
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"/>.
104         /// </summary>
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);
110         }
111
112         /// <summary>
113         /// Creates a <see cref="CatchBlock"/> representing a catch statement with a reference to the caught object for use in the handler body.
114         /// </summary>
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);
121         }
122
123         /// <summary>
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.
126         /// </summary>
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);
133         }
134
135         /// <summary>
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.
138         /// </summary>
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);
146         }
147
148         /// <summary>
149         /// Creates a <see cref="CatchBlock"/> representing a catch statement with the specified elements.
150         /// </summary>
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);
162             }
163             RequiresCanRead(body, "body");
164             if (filter != null) {
165                 RequiresCanRead(filter, "filter");
166                 if (filter.Type != typeof(bool)) throw Error.ArgumentMustBeBoolean();
167             }
168
169             return new CatchBlock(type, variable, body, filter);
170         }
171     }
172 }