forked from microsoft/qsharp-compiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Logging.cs
87 lines (77 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
// Copyright (c) Microsoft Corporation. All rights reserved.
// 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);
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.
/// Throws an ArgumentNullException if the given message is null.
/// </summary>
private static void PrintToConsole(DiagnosticSeverity severity, string message)
{
if (message == null) throw new ArgumentNullException(nameof(message));
var (stream, color) =
severity == DiagnosticSeverity.Error ? (Console.Error, ConsoleColor.Red) :
severity == 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; }
}
}
}