Commit 807d7759 authored by Jesse McGrew's avatar Jesse McGrew
Browse files

Refactor diagnostic logging to allow bypassing stderr.

parent 6ec63955d693
......@@ -44,6 +44,7 @@ namespace Zilf.Compiler
public sealed class FrontEnd
{
public IFileSystem FileSystem { get; init; } = PhysicalFileSystem.Instance;
public IDiagnosticLogger Logger { get; init; } = new DefaultDiagnosticLogger();
internal event EventHandler<ContextEventArgs>? InitializeContext;
......@@ -142,6 +143,7 @@ namespace Zilf.Compiler
Context NewContext(RunMode runMode, bool wantDebugInfo)
{
var result = new Context { RunMode = runMode, WantDebugInfo = wantDebugInfo };
result.DiagnosticManager.Logger = Logger;
InitializeContext?.Invoke(this, new ContextEventArgs(result));
......
/* Copyright 2010-2018 Jesse McGrew
*
* This file is part of ZILF.
*
* ZILF is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ZILF is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ZILF. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Globalization;
using System.IO;
using Zilf.Common;
namespace Zilf.Diagnostics
{
public class DefaultDiagnosticLogger : IDiagnosticLogger
{
public TextWriter Writer { get; init; } = Console.Error;
public DefaultDiagnosticLogger()
{
}
public void Log(Diagnostic diagnostic)
{
if (diagnostic == null)
throw new ArgumentNullException(nameof(diagnostic));
Writer.WriteLine(Format(diagnostic));
foreach (var sd in diagnostic.SubDiagnostics)
Writer.WriteLine(Format(sd, diagnostic));
if (diagnostic.StackTrace != null)
Writer.WriteLine(diagnostic.StackTrace);
}
protected static string FormatSeverity(Severity severity) => severity switch
{
Severity.Info => "info",
Severity.Warning => "warning",
Severity.Error => "error",
Severity.Fatal => "fatal",
_ => throw UnhandledCaseException.FromEnum(severity),
};
protected static string Format(Diagnostic diagnostic, bool includeSourceInfo = true)
{
if (diagnostic == null)
throw new ArgumentNullException(nameof(diagnostic));
const string SFormatWithSourceInfo = "[{0} {1}{2:0000}] {3}: {4}";
const string SFormatWithoutSourceInfo = "[{0} {1}{2:0000}] {4}";
return string.Format(
CultureInfo.CurrentCulture,
includeSourceInfo ? SFormatWithSourceInfo : SFormatWithoutSourceInfo,
FormatSeverity(diagnostic.Severity),
diagnostic.CodePrefix,
diagnostic.CodeNumber,
diagnostic.Location.SourceInfo,
diagnostic.GetFormattedMessage());
}
protected static string Format(Diagnostic diagnostic, Diagnostic parentDiagnostic)
{
if (diagnostic == null)
throw new ArgumentNullException(nameof(diagnostic));
if (parentDiagnostic == null)
throw new ArgumentNullException(nameof(parentDiagnostic));
bool includeSourceInfo = !string.IsNullOrEmpty(diagnostic.Location.SourceInfo) &&
diagnostic.Location != parentDiagnostic.Location &&
diagnostic.Location.SourceInfo != parentDiagnostic.Location.SourceInfo;
return Format(diagnostic, includeSourceInfo);
}
}
}
......@@ -43,15 +43,17 @@ namespace Zilf.Diagnostics
public bool WarningsAsErrors { get; set; }
public bool SuppressNoisyWarnings { get; set; }
public IDiagnosticFormatter Formatter { get; }
public TextWriter OutputWriter { get; }
public IDiagnosticLogger Logger { get; set; }
public event EventHandler? TooManyErrors;
public DiagnosticManager(IDiagnosticFormatter? formatter = null, TextWriter? outputWriter = null)
public DiagnosticManager() : this(new DefaultDiagnosticLogger())
{
Formatter = formatter ?? new DefaultDiagnosticFormatter();
OutputWriter = outputWriter ?? Console.Error;
}
public DiagnosticManager(IDiagnosticLogger logger)
{
Logger = logger;
}
public void Suppress(string code)
......@@ -98,7 +100,7 @@ namespace Zilf.Diagnostics
}
else
{
OutputWriter.WriteLine(Formatter.Format(diag));
Logger.Log(diag);
}
}
......
......@@ -18,8 +18,8 @@
namespace Zilf.Diagnostics
{
public interface IDiagnosticFormatter
public interface IDiagnosticLogger
{
string Format(Diagnostic diagnostic);
void Log(Diagnostic diagnostic);
}
}
......@@ -16,34 +16,19 @@
* along with ZILF. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Text;
namespace Zilf.Diagnostics
{
public class DefaultDiagnosticFormatter : IDiagnosticFormatter
public sealed class NullDiagnosticLogger : IDiagnosticLogger
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Not normalizing.")]
public string Format(Diagnostic diagnostic)
{
var sb = new StringBuilder(80);
sb.Append($"[{diagnostic.Severity.ToString().ToLowerInvariant()} {diagnostic.CodePrefix}{diagnostic.CodeNumber:0000}] {diagnostic.Location.SourceInfo}: ");
sb.Append(diagnostic.GetFormattedMessage());
foreach (var sd in diagnostic.SubDiagnostics)
{
sb.Append($"\n [{sd.Severity.ToString().ToLowerInvariant()} {sd.CodePrefix}{sd.CodeNumber:0000}] ");
sb.Append(sd.GetFormattedMessage());
}
public static readonly NullDiagnosticLogger Instance = new();
if (diagnostic.StackTrace != null)
{
sb.Append('\n');
sb.Append(diagnostic.StackTrace);
}
private NullDiagnosticLogger()
{
}
return sb.ToString();
public void Log(Diagnostic diagnostic)
{
// nada
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment