MegaBites-AI/Windows-powershell
0308
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4// The define below is only valid for this file. It allows the methods5// defined here to call Diagnostics.Assert when only ASSERTIONS_TRACE is defined6// Any #if DEBUG is pointless (always true) in this file because of this declaration.7// The presence of the define will cause the System.Diagnostics.Debug.Asser calls8// always to be compiled in for this file. What can be compiled out are the calls to9// System.Management.Automation.Diagnostics.Assert in other files when neither DEBUG10// nor ASSERTIONS_TRACE is defined.11#define DEBUG12 13using System.Diagnostics;14using System.Diagnostics.CodeAnalysis;15using System.Text;16 17namespace System.Management.Automation18{19 /// <summary>20 /// Exception with a full stack trace excluding the last two frames.21 /// </summary>22 internal class AssertException : SystemException23 {24 /// <summary>25 /// Calls the base class with message and sets the stack frame.26 /// </summary>27 /// <param name="message">Repassed to the base class.</param>28 internal AssertException(string message) : base(message)29 {30 // 3 will skip the assertion caller, this method and AssertException.StackTrace31 StackTrace = Diagnostics.StackTrace(3);32 }33 34 /// <summary>35 /// Returns the stack trace set in the constructor.36 /// </summary>37 /// <value>the constructor's stackTrace</value>38 public override string StackTrace { get; }39 }40 41 /// <summary>42 /// This class contain the few methods necessary for43 /// the basic assertion use.44 /// </summary>45 /// <remarks>46 /// All methods are public and static.47 /// The class cannot derive from the sealed System.Diagnostics.Debug48 /// The class was also made sealed.49 /// <newpara/>50 /// <example>51 /// <code>52 /// Diagnostics.Assert(x >= 0,"A negative x would have caused early return.");53 /// </code>54 /// </example>55 /// <newpara/>56 /// </remarks>57 internal sealed class Diagnostics58 {59 internal static string StackTrace(int framesToSkip)60 {61 StackTrace trace = new StackTrace(true);62 StackFrame[] frames = trace.GetFrames();63 StringBuilder frameString = new StringBuilder();64 int maxFrames = 10;65 maxFrames += framesToSkip;66 for (int i = framesToSkip; (i < frames.Length) && (i < maxFrames); i++)67 {68 StackFrame frame = frames[i];69 frameString.Append(frame.ToString());70 }71 72 return frameString.ToString();73 }74 75 private static readonly object s_throwInsteadOfAssertLock = 1;76 77 private static bool s_throwInsteadOfAssert = false;78 /// <summary>79 /// If set to true will prevent the assertion dialog from showing up80 /// by throwing an exception instead of calling Debug.Assert.81 /// </summary>82 /// <value>false for dialog, true for exception</value>83 internal static bool ThrowInsteadOfAssert84 {85 get86 {87 lock (s_throwInsteadOfAssertLock)88 {89 return s_throwInsteadOfAssert;90 }91 }92 93 set94 {95 lock (s_throwInsteadOfAssertLock)96 {97 s_throwInsteadOfAssert = value;98 }99 }100 }101 102 /// <summary>103 /// This class only has statics, so we shouldn't need to instantiate any object.104 /// </summary>105 private Diagnostics() { }106 107 /// <summary>108 /// Basic assertion with logical condition and message.109 /// </summary>110 /// <param name="condition">111 /// logical condition that should be true for program to proceed112 /// </param>113 /// <param name="whyThisShouldNeverHappen">114 /// Message to explain why condition should always be true115 /// </param>116 // These two lines are playing havoc with asmmeta. Since only one asmmeta file117 // can be checked in at a time if you compile the asmmeta for a fre build then118 // the checked can't compile against it since these methods will not exist. If119 // you check in the chk asmmeta the fre build will not compile because it is120 // not expecting these methods to exist.121 [System.Diagnostics.Conditional("DEBUG")]122 [System.Diagnostics.Conditional("ASSERTIONS_TRACE")]123 internal static void Assert(124 [DoesNotReturnIf(false)]125 bool condition,126 string whyThisShouldNeverHappen)127 {128 Diagnostics.Assert(condition, whyThisShouldNeverHappen, string.Empty);129 }130 131 /// <summary>132 /// Basic assertion with logical condition, message and detailed message.133 /// </summary>134 /// <param name="condition">135 /// logical condition that should be true for program to proceed136 /// </param>137 /// <param name="whyThisShouldNeverHappen">138 /// Message to explain why condition should always be true139 /// </param>140 /// <param name="detailMessage">141 /// Additional information about the assertion142 /// </param>143 // These two lines are playing havoc with asmmeta. Since only one asmmeta file144 // can be checked in at a time if you compile the asmmeta for a fre build then145 // the checked can't compile against it since these methods will not exist. If146 // you check in the chk asmmeta the fre build will not compile because it is147 // not expecting these methods to exist.148 [System.Diagnostics.Conditional("DEBUG")]149 [System.Diagnostics.Conditional("ASSERTIONS_TRACE")]150 internal static void Assert(151 [DoesNotReturnIf(false)]152 bool condition,153 string whyThisShouldNeverHappen,154 string detailMessage)155 {156 // Early out avoids some slower code below (mostly the locking done in ThrowInsteadOfAssert).157 if (condition)158 {159 return;160 }161 162#if ASSERTIONS_TRACE163 if (!condition)164 {165 if (Diagnostics.ThrowInsteadOfAssert)166 {167 string assertionMessage = "ASSERT: " + whyThisShouldNeverHappen + " " + detailMessage + " ";168 AssertException e = new AssertException(assertionMessage);169 tracer.TraceException(e);170 throw e;171 }172 173 StringBuilder builder = new StringBuilder();174 builder.Append("ASSERT: ");175 builder.Append(whyThisShouldNeverHappen);176 builder.Append(".");177 if (detailMessage.Length != 0)178 {179 builder.Append(detailMessage);180 builder.Append(".");181 }182 // 2 to skip this method and Diagnostics.StackTace183 builder.Append(Diagnostics.StackTrace(2));184 tracer.TraceError(builder.ToString());185 }186#else187 if (Diagnostics.ThrowInsteadOfAssert)188 {189 string assertionMessage = "ASSERT: " + whyThisShouldNeverHappen + " " + detailMessage + " ";190 throw new AssertException(assertionMessage);191 }192 193 System.Diagnostics.Debug.Fail(whyThisShouldNeverHappen, detailMessage);194#endif195 }196 }197}198 