Fix warnings in mscorlib's Test suite + bring a couple more tests + fix thread rename...
[mono.git] / mcs / class / corlib / System.Diagnostics.Contracts.Internal / ContractHelper.cs
1 //
2 // System.Diagnostics.Contracts.Internal.ContractHelper.cs
3 //
4 // Authors:
5 //    Chris Bacon (chrisbacon76@gmail.com)
6 //
7 // Copyright 2010 Novell (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 #if NET_4_0
30
31 using System;
32 using System.Text;
33 using System.Reflection;
34 using System.Runtime.ConstrainedExecution;
35
36 namespace System.Diagnostics.Contracts.Internal
37 {
38 #if NET_4_5
39         [Obsolete ("Type has been moved to System.Runtime.CompilerServices")]
40 #endif
41         public static class ContractHelper
42         {
43                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
44                 [DebuggerNonUserCode]
45                 public static string RaiseContractFailedEvent (ContractFailureKind failureKind, string userMessage, string conditionText, Exception innerException)
46                 {
47
48                         StringBuilder msg = new StringBuilder (60);
49                         switch (failureKind) {
50                         case ContractFailureKind.Assert:
51                                 msg.Append ("Assertion failed");
52                                 break;
53                         case ContractFailureKind.Assume:
54                                 msg.Append ("Assumption failed");
55                                 break;
56                         case ContractFailureKind.Invariant:
57                                 msg.Append ("Invariant failed");
58                                 break;
59                         case ContractFailureKind.Postcondition:
60                                 msg.Append ("Postcondition failed");
61                                 break;
62                         case ContractFailureKind.PostconditionOnException:
63                                 msg.Append ("Postcondition failed after throwing an exception");
64                                 break;
65                         case ContractFailureKind.Precondition:
66                                 msg.Append ("Precondition failed");
67                                 break;
68                         default:
69                                 throw new NotSupportedException ("Not supported: " + failureKind);
70                         }
71                         if (conditionText != null) {
72                                 msg.Append (": ");
73                                 msg.Append (conditionText);
74                         } else {
75                                 msg.Append ('.');
76                         }
77                         if (userMessage != null) {
78                                 msg.Append ("  ");
79                                 msg.Append (userMessage);
80                         }
81                         string msgString = msg.ToString ();
82
83                         Exception handlerException = null;
84                         bool unwind = false, handled = false;
85
86                         var contractFailed = Contract.InternalContractFailedEvent;
87                         if (contractFailed != null) {
88                                 // Execute all event handlers
89                                 var handlers = contractFailed.GetInvocationList ();
90                                 var e = new ContractFailedEventArgs (failureKind, msgString, conditionText, innerException);
91                                 foreach (var handler in handlers) {
92                                         try {
93                                                 handler.DynamicInvoke (null, e);
94                                         } catch (Exception ex) {
95                                                 e.SetUnwind ();
96                                                 // If multiple handlers throw an exception then the specification states that it
97                                                 // is undetermined which one becomes the InnerException.
98                                                 handlerException = ex.InnerException;
99                                         }
100                                 }
101                                 unwind = e.Unwind;
102                                 handled = e.Handled;
103                         }
104
105                         if (unwind) {
106                                 Exception ex = innerException ?? handlerException;
107                                 throw new ContractException (msgString, failureKind, conditionText, userMessage, ex);
108                         }
109
110                         return handled ? null : msgString;
111                 }
112
113                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
114                 [DebuggerNonUserCode]
115                 public static void TriggerFailure (ContractFailureKind kind, string displayMessage, string userMessage, string conditionText, Exception innerException)
116                 {
117                         StringBuilder msg = new StringBuilder (50);
118
119                         if (conditionText != null) {
120                                 msg.Append ("Expression: ");
121                                 msg.AppendLine (conditionText);
122                         }
123                         msg.Append ("Description: ");
124                         if (displayMessage != null) {
125                                 msg.Append (displayMessage);
126                         }
127                         if (Environment.UserInteractive) {
128                                 // FIXME: This should trigger an assertion.
129                                 // But code will never get here at the moment, as Environment.UserInteractive currently
130                                 // always returns false.
131                                 throw new ContractShouldAssertException (msg.ToString ());
132                         } else {
133                                 // Note that FailFast() currently throws a NotImplementedException()
134                                 Environment.FailFast(msg.ToString()/*, new ExecutionEngineException()*/);
135                         }
136                 }
137
138         }
139
140 }
141
142 #endif