Merge pull request #4155 from BrzVlad/fix-tls-lmf-addr
[mono-project.git] / mcs / class / dlr / Runtime / Microsoft.Scripting.Core / Ast / CatchBlock.cs
blob08e2ab595026f33048c9c48db993cdbaeac33b27
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 * ***************************************************************************/
16 using System;
17 using System.Diagnostics;
18 using System.Dynamic.Utils;
20 #if !FEATURE_CORE_DLR
21 namespace Microsoft.Scripting.Ast {
22 #else
23 namespace System.Linq.Expressions {
24 #endif
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;
37 internal CatchBlock(Type test, ParameterExpression variable, Expression body, Expression filter) {
38 _test = test;
39 _var = variable;
40 _body = body;
41 _filter = filter;
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; }
51 /// <summary>
52 /// Gets the type of <see cref="Exception"/> this handler catches.
53 /// </summary>
54 public Type Test {
55 get { return _test; }
58 /// <summary>
59 /// Gets the body of the catch block.
60 /// </summary>
61 public Expression Body {
62 get { return _body; }
65 /// <summary>
66 /// Gets the body of the <see cref="CatchBlock"/>'s filter.
67 /// </summary>
68 public Expression Filter {
69 get {
70 return _filter;
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);
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;
95 return Expression.MakeCatchBlock(Test, variable, body, filter);
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);
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);
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);
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);
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);
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);