BindingFlags.Public needed here as Exception.HResult is now public in .NET 4.5. This...
[mono.git] / mcs / class / corlib / System.Diagnostics.Contracts / Contract.cs
1 //
2 // System.Diagnostics.Contracts.Contract.cs
3 //
4 // Authors:
5 //    Miguel de Icaza (miguel@gnome.org)
6 //    Chris Bacon (chrisbacon76@gmail.com)
7 //    Marek Safar (marek.safar@gmail.com)
8 //
9 // Copyright 2009, 2010 Novell (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 #if NET_4_0 || MOONLIGHT
32
33 using System;
34 using System.Collections.Generic;
35 using System.Diagnostics.Contracts.Internal;
36 using System.Runtime.ConstrainedExecution;
37
38 namespace System.Diagnostics.Contracts
39 {
40         public static class Contract
41         {
42                 public static event EventHandler<ContractFailedEventArgs> ContractFailed;
43
44                 // Used in test
45                 internal static EventHandler<ContractFailedEventArgs> InternalContractFailedEvent {
46                         get { return ContractFailed; }
47                 }
48
49                 // Used in test
50                 internal static Type GetContractExceptionType ()
51                 {
52                         return typeof (ContractException);
53                 }
54
55                 // Used in test
56                 internal static Type GetContractShouldAssertExceptionType ()
57                 {
58                         return typeof (ContractShouldAssertException);
59                 }
60
61                 static void ReportFailure (ContractFailureKind kind, string userMessage, string conditionText, Exception innerException)
62                 {
63                         string msg = ContractHelper.RaiseContractFailedEvent (kind, userMessage, conditionText, innerException);
64                         // if msg is null, then it has been handled already, so don't do anything here
65                         if (msg != null)
66                                 ContractHelper.TriggerFailure (kind, msg, userMessage, conditionText, innerException);
67                 }
68
69                 static void AssertMustUseRewriter (ContractFailureKind kind, string message)
70                 {
71                         ContractHelper.TriggerFailure (kind, "Assembly must be re-written by the code contract rewritter", null, message, null);
72                 }
73
74                 [ConditionalAttribute("CONTRACTS_FULL")]
75                 [ConditionalAttribute("DEBUG")]
76                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
77                 public static void Assert (bool condition)
78                 {
79                         if (condition)
80                                 return;
81
82                         ReportFailure (ContractFailureKind.Assert, null, null, null);
83                 }
84
85                 [ConditionalAttribute("DEBUG")]
86                 [ConditionalAttribute("CONTRACTS_FULL")]
87                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
88                 public static void Assert (bool condition, string userMessage)
89                 {
90                         if (condition)
91                                 return;
92
93                         ReportFailure (ContractFailureKind.Assert, userMessage, null, null);
94                 }
95
96                 [ConditionalAttribute("DEBUG")]
97                 [ConditionalAttribute("CONTRACTS_FULL")]
98                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
99                 public static void Assume(bool condition)
100                 {
101                         // At runtime, this behaves like assert
102                         if (condition)
103                                 return;
104
105                         ReportFailure (ContractFailureKind.Assume, null, null, null);
106                 }
107
108                 [ConditionalAttribute("CONTRACTS_FULL")]
109                 [ConditionalAttribute("DEBUG")]
110                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
111                 public static void Assume (bool condition, string userMessage)
112                 {
113                         // At runtime, this behaves like assert
114                         if (condition)
115                                 return;
116
117                         ReportFailure (ContractFailureKind.Assume, userMessage, null, null);
118                 }
119
120                 [ConditionalAttribute("CONTRACTS_FULL")]
121                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
122                 public static void EndContractBlock ()
123                 {
124                         // Marker method, no code required.
125                 }
126
127                 [ConditionalAttribute("CONTRACTS_FULL")]
128                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
129                 public static void Ensures (bool condition)
130                 {
131                         AssertMustUseRewriter (ContractFailureKind.Postcondition, "Contract.Ensures");
132                 }
133
134                 [ConditionalAttribute("CONTRACTS_FULL")]
135                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
136                 public static void Ensures (bool condition, string userMessage)
137                 {
138                         AssertMustUseRewriter (ContractFailureKind.Postcondition, "Contract.Ensures");
139                 }
140
141                 [ConditionalAttribute("CONTRACTS_FULL")]
142                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
143                 public static void EnsuresOnThrow<TException> (bool condition) where TException : Exception
144                 {
145                         AssertMustUseRewriter (ContractFailureKind.Postcondition, "Contract.EnsuresOnThrow");
146                 }
147
148                 [ConditionalAttribute("CONTRACTS_FULL")]
149                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
150                 public static void EnsuresOnThrow<TException> (bool condition, string userMessage) where TException : Exception
151                 {
152                         AssertMustUseRewriter (ContractFailureKind.Postcondition, "Contract.EnsuresOnThrow");
153                 }
154
155                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
156                 public static bool Exists<T> (IEnumerable<T> collection, Predicate<T> predicate)
157                 {
158                         if (predicate == null)
159                                 throw new ArgumentNullException ("predicate");
160                         if (collection == null)
161                                 throw new ArgumentNullException ("collection");
162                         
163                         foreach (var t in collection)
164                                 if (predicate (t))
165                                         return true;
166                         return false;
167                 }
168
169                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
170                 public static bool Exists (int fromInclusive, int toExclusive, Predicate<int> predicate)
171                 {
172                         if (predicate == null)
173                                 throw new ArgumentNullException ("predicate");
174                         if (toExclusive < fromInclusive)
175                                 throw new ArgumentException ("toExclusitve < fromInclusive");
176                         
177                         for (int i = fromInclusive; i < toExclusive; i++)
178                                 if (predicate (i))
179                                         return true;
180
181                         return false;
182                 }
183
184                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
185                 public static bool ForAll<T> (IEnumerable<T> collection, Predicate<T> predicate)
186                 {
187                         if (predicate == null)
188                                 throw new ArgumentNullException ("predicate");
189                         if (collection == null)
190                                 throw new ArgumentNullException ("collection");
191                         
192                         foreach (var t in collection)
193                                 if (!predicate (t))
194                                         return false;
195
196                         return true;
197                 }
198
199                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
200                 public static bool ForAll (int fromInclusive, int toExclusive, Predicate<int> predicate)
201                 {
202                         if (predicate == null)
203                                 throw new ArgumentNullException ("predicate");
204                         if (toExclusive < fromInclusive)
205                                 throw new ArgumentException ("toExclusitve < fromInclusive");
206                         
207                         for (int i = fromInclusive; i < toExclusive; i++)
208                                 if (!predicate (i))
209                                         return false;
210
211                         return true;
212                 }
213
214                 [ConditionalAttribute("CONTRACTS_FULL")]
215                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
216                 public static void Invariant (bool condition)
217                 {
218                         AssertMustUseRewriter (ContractFailureKind.Invariant, "Contract.Invariant");
219                 }
220
221                 [ConditionalAttribute("CONTRACTS_FULL")]
222                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
223                 public static void Invariant (bool condition, string userMessage)
224                 {
225                         AssertMustUseRewriter (ContractFailureKind.Invariant, "Contract.Invariant");
226                 }
227
228                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
229                 public static T OldValue<T> (T value)
230                 {
231                         // Marker method, no code required.
232                         return default (T);
233                 }
234
235                 [ConditionalAttribute("CONTRACTS_FULL")]
236                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
237                 public static void Requires (bool condition)
238                 {
239                         AssertMustUseRewriter (ContractFailureKind.Precondition, "Contract.Requires");
240                 }
241
242                 [ConditionalAttribute("CONTRACTS_FULL")]
243                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
244                 public static void Requires (bool condition, string userMessage)
245                 {
246                         AssertMustUseRewriter (ContractFailureKind.Precondition, "Contract.Requires");
247                 }
248
249                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
250                 public static void Requires<TException> (bool condition) where TException : Exception
251                 {
252                         AssertMustUseRewriter (ContractFailureKind.Precondition, "Contract.Requires<TException>");
253                 }
254
255                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
256                 public static void Requires<TException> (bool condition, string userMessage) where TException : Exception
257                 {
258                         AssertMustUseRewriter (ContractFailureKind.Precondition, "Contract.Requires<TException>");
259                 }
260
261                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
262                 public static T Result<T> ()
263                 {
264                         // Marker method, no code required.
265                         return default (T);
266                 }
267
268                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
269                 public static T ValueAtReturn<T> (out T value)
270                 {
271                         // Marker method, no code required.
272                         return value = default (T);
273                 }
274         }
275 }
276
277 #endif