2 // System.Diagnostics.Contracts.Internal.ContractHelper.cs
5 // Chris Bacon (chrisbacon76@gmail.com)
7 // Copyright 2010 Novell (http://www.novell.com)
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 #if NET_4_0 || NET_2_1
33 using System
.Reflection
;
34 using System
.Runtime
.ConstrainedExecution
;
36 namespace System
.Diagnostics
.Contracts
.Internal
39 [Obsolete ("Type has been moved to System.Runtime.CompilerServices")]
41 public static class ContractHelper
44 const string SystemWindowsBrowser
= ", System.Windows.Browser, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e";
45 const string HtmlPage
= "System.Windows.Browser.HtmlPage" + SystemWindowsBrowser
;
46 const string HtmlWindow
= "System.Windows.Browser.HtmlWindow" + SystemWindowsBrowser
;
47 static MethodInfo alert
;
50 static ContractHelper ()
52 Type htmlpage
= Type
.GetType (HtmlPage
);
53 MethodInfo get_window
= htmlpage
.GetMethod ("get_Window", BindingFlags
.Static
| BindingFlags
.Public
);
54 window
= get_window
.Invoke (null, null);
55 Type htmlwindow
= Type
.GetType (HtmlWindow
);
56 alert
= htmlwindow
.GetMethod ("Alert", BindingFlags
.Instance
| BindingFlags
.Public
);
60 [ReliabilityContract (Consistency
.WillNotCorruptState
, Cer
.Success
)]
62 public static string RaiseContractFailedEvent (ContractFailureKind failureKind
, string userMessage
, string conditionText
, Exception innerException
)
65 StringBuilder msg
= new StringBuilder (60);
66 switch (failureKind
) {
67 case ContractFailureKind
.Assert
:
68 msg
.Append ("Assertion failed");
70 case ContractFailureKind
.Assume
:
71 msg
.Append ("Assumption failed");
73 case ContractFailureKind
.Invariant
:
74 msg
.Append ("Invariant failed");
76 case ContractFailureKind
.Postcondition
:
77 msg
.Append ("Postcondition failed");
79 case ContractFailureKind
.PostconditionOnException
:
80 msg
.Append ("Postcondition failed after throwing an exception");
82 case ContractFailureKind
.Precondition
:
83 msg
.Append ("Precondition failed");
86 throw new NotSupportedException ("Not supported: " + failureKind
);
88 if (conditionText
!= null) {
90 msg
.Append (conditionText
);
94 if (userMessage
!= null) {
96 msg
.Append (userMessage
);
98 string msgString
= msg
.ToString ();
100 Exception handlerException
= null;
101 bool unwind
= false, handled
= false;
103 var contractFailed
= Contract
.InternalContractFailedEvent
;
104 if (contractFailed
!= null) {
105 // Execute all event handlers
106 var handlers
= contractFailed
.GetInvocationList ();
107 var e
= new ContractFailedEventArgs (failureKind
, msgString
, conditionText
, innerException
);
108 foreach (var handler
in handlers
) {
110 handler
.DynamicInvoke (null, e
);
111 } catch (Exception ex
) {
113 // If multiple handlers throw an exception then the specification states that it
114 // is undetermined which one becomes the InnerException.
115 handlerException
= ex
.InnerException
;
123 Exception ex
= innerException
?? handlerException
;
124 throw new ContractException (msgString
, failureKind
, conditionText
, userMessage
, ex
);
127 return handled
? null : msgString
;
130 [ReliabilityContract (Consistency
.WillNotCorruptState
, Cer
.Success
)]
131 [DebuggerNonUserCode
]
132 public static void TriggerFailure (ContractFailureKind kind
, string displayMessage
, string userMessage
, string conditionText
, Exception innerException
)
134 StringBuilder msg
= new StringBuilder (50);
136 if (conditionText
!= null) {
137 msg
.Append ("Expression: ");
138 msg
.AppendLine (conditionText
);
140 msg
.Append ("Description: ");
141 if (displayMessage
!= null) {
142 msg
.Append (displayMessage
);
145 // Silverlight shows a dialog that let you Abort (kill process/browser), Retry or Ignore
146 // Moonlight will simply warn and ignore (at least until FailFast is implemented)
147 // using reflection into System.Windows.Browser to popup an browser alert
148 alert
.Invoke (window
, new object [] { msg.ToString () }
);
150 if (Environment
.UserInteractive
) {
151 // FIXME: This should trigger an assertion.
152 // But code will never get here at the moment, as Environment.UserInteractive currently
153 // always returns false.
154 throw new ContractShouldAssertException (msg
.ToString ());
156 // Note that FailFast() currently throws a NotImplementedException()
157 Environment
.FailFast(msg
.ToString()/*, new ExecutionEngineException()*/);