This repository has been archived by the owner on Jan 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 169
/
Logging.cs
98 lines (88 loc) · 4.06 KB
/
Logging.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.LanguageServer.Protocol;
namespace Microsoft.Quantum.QsCompiler.Diagnostics
{
/// <summary>
/// Provides a logger that logs all diagnostics and information generated by the Q# command line compiler to the console.
/// </summary>
public class ConsoleLogger : LogTracker
{
private readonly Func<Diagnostic, string> applyFormatting;
protected internal virtual string Format(Diagnostic msg) =>
this.applyFormatting(msg);
/// <inheritdoc/>
protected sealed override void Print(Diagnostic msg) =>
PrintToConsole(msg.Severity, this.Format(msg));
/// <summary>
/// Construct a logger that uses the given function (if any) to format all diagnostics prior to logging them to the console.
/// If no function is specified, the format for logged diagnostics is optimized for readability.
/// All diagnostics that are as severe as or more severe than the specified verbosity (if any) are logged.
/// If the verbosity is left unspecified, all errors and warnings are logged.
/// Warnings that are listed under noWarn (if any) are suppressed.
/// If a line number offset is specified, then the ranges for all logged diagnostics are shifted by the spedified offset.
/// </summary>
public ConsoleLogger(
Func<Diagnostic, string>? format = null,
DiagnosticSeverity verbosity = DiagnosticSeverity.Warning,
IEnumerable<int>? noWarn = null,
int lineNrOffset = 0)
: base(verbosity, noWarn, lineNrOffset) =>
this.applyFormatting = format ?? Formatting.HumanReadableFormat;
/// <summary>
/// Prints the given message to the Console.
/// Errors and Warnings are printed to the error stream.
/// </summary>
private static void PrintToConsole(DiagnosticSeverity? severity, string message)
{
var (stream, color) = severity switch
{
DiagnosticSeverity.Error => (Console.Error, ConsoleColor.Red),
DiagnosticSeverity.Warning => (Console.Error, ConsoleColor.Yellow),
_ => (Console.Out, Console.ForegroundColor),
};
var consoleColor = Console.ForegroundColor;
Console.ForegroundColor = color;
try
{
var output = message;
stream.WriteLine(output);
}
finally
{
Console.ForegroundColor = consoleColor;
}
}
/// <summary>
/// Prints a summary containing the currently counted number of errors, warnings and exceptions.
/// Indicates a compilation failure if the given status does not correspond to the ReturnCode indicating a success.
/// </summary>
public virtual void ReportSummary(int status = CommandLineCompiler.ReturnCode.Success)
{
string ItemString(int nr, string name) => $"{nr} {name}{(nr == 1 ? "" : "s")}";
var errors = ItemString(this.NrErrorsLogged, "error");
var warnings = ItemString(this.NrWarningsLogged, "warning");
var exceptions = this.NrExceptionsLogged > 0
? $"\n{ItemString(this.NrExceptionsLogged, "logged exception")}"
: "";
Console.WriteLine("\n____________________________________________\n");
if (status == CommandLineCompiler.ReturnCode.Success)
{
Console.WriteLine($"Q#: Success! ({errors}, {warnings}) {exceptions}\n");
return;
}
var color = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
try
{
Console.WriteLine($"Q# compilation failed: {errors}, {warnings} {exceptions}\n");
}
finally
{
Console.ForegroundColor = color;
}
}
}
}