// 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 a set of properties and methods for debugging code. /// public static partial class Debug { private static readonly object s_lock = new object(); public static bool AutoFlush { get { return true; } set { } } [ThreadStatic] private static int s_indentLevel; public static int IndentLevel { get { return s_indentLevel; } set { s_indentLevel = value < 0 ? 0 : value; } } private static int s_indentSize = 4; public static int IndentSize { get { return s_indentSize; } set { s_indentSize = value < 0 ? 0 : value; } } [System.Diagnostics.Conditional("DEBUG")] public static void Close() { } [System.Diagnostics.Conditional("DEBUG")] public static void Flush() { } [System.Diagnostics.Conditional("DEBUG")] public static void Indent() { IndentLevel++; } [System.Diagnostics.Conditional("DEBUG")] public static void Unindent() { IndentLevel--; } [System.Diagnostics.Conditional("DEBUG")] public static void Print(string message) { Write(message); } [System.Diagnostics.Conditional("DEBUG")] public static void Print(string format, params object[] args) { Write(string.Format(null, format, args)); } private static readonly object s_ForLock = new Object(); [System.Diagnostics.Conditional("DEBUG")] public static void Assert(bool condition) { Assert(condition, string.Empty, string.Empty); } [System.Diagnostics.Conditional("DEBUG")] public static void Assert(bool condition, string message) { Assert(condition, message, string.Empty); } [System.Diagnostics.Conditional("DEBUG")] public static void Assert(bool condition, string message, string detailMessage) { if (!condition) { string stackTrace; try { stackTrace = Internal.Runtime.Augments.EnvironmentAugments.StackTrace; } catch { stackTrace = ""; } WriteLine(FormatAssert(stackTrace, message, detailMessage)); s_ShowAssertDialog(stackTrace, message, detailMessage); } } [System.Diagnostics.Conditional("DEBUG")] public static void Fail(string message) { Assert(false, message, string.Empty); } [System.Diagnostics.Conditional("DEBUG")] public static void Fail(string message, string detailMessage) { Assert(false, message, detailMessage); } private static string FormatAssert(string stackTrace, string message, string detailMessage) { string newLine = GetIndentString() + Environment.NewLine; return SR.DebugAssertBanner + newLine + SR.DebugAssertShortMessage + newLine + message + newLine + SR.DebugAssertLongMessage + newLine + detailMessage + newLine + stackTrace; } [System.Diagnostics.Conditional("DEBUG")] public static void Assert(bool condition, string message, string detailMessageFormat, params object[] args) { Assert(condition, message, string.Format(detailMessageFormat, args)); } [System.Diagnostics.Conditional("DEBUG")] public static void WriteLine(string message) { Write(message + Environment.NewLine); } [System.Diagnostics.Conditional("DEBUG")] public static void Write(string message) { lock (s_lock) { if (message == null) { s_WriteCore(string.Empty); return; } if (s_needIndent) { message = GetIndentString() + message; s_needIndent = false; } s_WriteCore(message); if (message.EndsWith(Environment.NewLine)) { s_needIndent = true; } } } [System.Diagnostics.Conditional("DEBUG")] public static void WriteLine(object value) { WriteLine(value?.ToString()); } [System.Diagnostics.Conditional("DEBUG")] public static void WriteLine(object value, string category) { WriteLine(value?.ToString(), category); } [System.Diagnostics.Conditional("DEBUG")] public static void WriteLine(string format, params object[] args) { WriteLine(string.Format(null, format, args)); } [System.Diagnostics.Conditional("DEBUG")] public static void WriteLine(string message, string category) { if (category == null) { WriteLine(message); } else { WriteLine(category + ":" + message); } } [System.Diagnostics.Conditional("DEBUG")] public static void Write(object value) { Write(value?.ToString()); } [System.Diagnostics.Conditional("DEBUG")] public static void Write(string message, string category) { if (category == null) { Write(message); } else { Write(category + ":" + message); } } [System.Diagnostics.Conditional("DEBUG")] public static void Write(object value, string category) { Write(value?.ToString(), category); } [System.Diagnostics.Conditional("DEBUG")] public static void WriteIf(bool condition, string message) { if (condition) { Write(message); } } [System.Diagnostics.Conditional("DEBUG")] public static void WriteIf(bool condition, object value) { if (condition) { Write(value); } } [System.Diagnostics.Conditional("DEBUG")] public static void WriteIf(bool condition, string message, string category) { if (condition) { Write(message, category); } } [System.Diagnostics.Conditional("DEBUG")] public static void WriteIf(bool condition, object value, string category) { if (condition) { Write(value, category); } } [System.Diagnostics.Conditional("DEBUG")] public static void WriteLineIf(bool condition, object value) { if (condition) { WriteLine(value); } } [System.Diagnostics.Conditional("DEBUG")] public static void WriteLineIf(bool condition, object value, string category) { if (condition) { WriteLine(value, category); } } [System.Diagnostics.Conditional("DEBUG")] public static void WriteLineIf(bool condition, string message) { if (condition) { WriteLine(message); } } [System.Diagnostics.Conditional("DEBUG")] public static void WriteLineIf(bool condition, string message, string category) { if (condition) { WriteLine(message, category); } } private static bool s_needIndent; private static string s_indentString; private static string GetIndentString() { int indentCount = IndentSize * IndentLevel; if (s_indentString?.Length == indentCount) { return s_indentString; } return s_indentString = new string(' ', indentCount); } private sealed class DebugAssertException : Exception { internal DebugAssertException(string message, string detailMessage, string stackTrace) : base(message + Environment.NewLine + detailMessage + Environment.NewLine + stackTrace) { } } // internal and not readonly so that the tests can swap this out. internal static Action s_ShowAssertDialog = ShowAssertDialog; internal static Action s_WriteCore = WriteCore; } }