// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. // Do not remove this, it is needed to retain calls to these conditional methods in release builds #define DEBUG namespace System.Diagnostics { /// /// Provides default implementation for Write and Fail methods in Debug class. /// public partial class DebugProvider { public virtual void Fail(string? message, string? detailMessage) { string stackTrace; try { stackTrace = new StackTrace(0, true).ToString(System.Diagnostics.StackTrace.TraceFormat.Normal); } catch { stackTrace = ""; } WriteAssert(stackTrace, message, detailMessage); FailCore(stackTrace, message, detailMessage, "Assertion failed."); } internal void WriteAssert(string stackTrace, string? message, string? detailMessage) { WriteLine(SR.DebugAssertBanner + Environment.NewLineConst + SR.DebugAssertShortMessage + Environment.NewLineConst + message + Environment.NewLineConst + SR.DebugAssertLongMessage + Environment.NewLineConst + detailMessage + Environment.NewLineConst + stackTrace); } public virtual void Write(string? message) { lock (s_lock) { if (message == null) { WriteCore(string.Empty); return; } if (_needIndent) { message = GetIndentString() + message; _needIndent = false; } WriteCore(message); if (message.EndsWith(Environment.NewLineConst)) { _needIndent = true; } } } public virtual void WriteLine(string? message) { Write(message + Environment.NewLineConst); } public virtual void OnIndentLevelChanged(int indentLevel) { } public virtual void OnIndentSizeChanged(int indentSize) { } private static readonly object s_lock = new object(); private sealed class DebugAssertException : Exception { internal DebugAssertException(string? message, string? detailMessage, string? stackTrace) : base(Terminate(message) + Terminate(detailMessage) + stackTrace) { } private static string? Terminate(string? s) { if (s == null) return s; s = s.Trim(); if (s.Length > 0) s += Environment.NewLineConst; return s; } } private bool _needIndent = true; private string? _indentString; private string GetIndentString() { int indentCount = Debug.IndentSize * Debug.IndentLevel; if (_indentString?.Length == indentCount) { return _indentString; } return _indentString = new string(' ', indentCount); } // internal and not readonly so that the tests can swap this out. internal static Action? s_FailCore = null; internal static Action? s_WriteCore = null; } }