// 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;
}
}