DiagnosticManager.cs 3.9 KB
Newer Older
1
/* Copyright 2010-2018 Jesse McGrew
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 * 
 * 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;
20
using System.Collections.Generic;
21
using System.IO;
22
using System.Linq;
23
24
25
26
27
28
using JetBrains.Annotations;

namespace Zilf.Diagnostics
{
    sealed class DiagnosticManager
    {
Jesse McGrew's avatar
Jesse McGrew committed
29
30
        const int MaxErrorCount = 100;

31
32
33
        [NotNull]
        readonly List<Diagnostic> diagnostics = new List<Diagnostic>();

34
35
36
37
38
39
        [NotNull]
        readonly List<Diagnostic> suppressedDiagnostics = new List<Diagnostic>();

        [NotNull]
        readonly HashSet<string> suppressions = new HashSet<string>();

40
41
        bool suppressAllTheThings = false;

42
43
44
45
        [NotNull]
        public IReadOnlyCollection<Diagnostic> Diagnostics => diagnostics;
        public int ErrorCount => Diagnostics.Count(d => d.Severity == Severity.Error || d.Severity == Severity.Fatal);
        public int WarningCount => Diagnostics.Count(d => d.Severity == Severity.Warning);
46
        public int SuppressedWarningCount => suppressedDiagnostics.Count(d => d.Severity == Severity.Warning);
47

48
        public bool WarningsAsErrors { get; set; }
49
        public bool SuppressNoisyWarnings { get; set; }
50

51
        [NotNull]
52
        public IDiagnosticFormatter Formatter { get; }
53
        [NotNull]
54
55
56
57
58
59
60
61
62
63
        public TextWriter OutputWriter { get; }

        public event EventHandler TooManyErrors;

        public DiagnosticManager([CanBeNull] IDiagnosticFormatter formatter = null, [CanBeNull] TextWriter outputWriter = null)
        {
            Formatter = formatter ?? new DefaultDiagnosticFormatter();
            OutputWriter = outputWriter ?? Console.Error;
        }

64
65
66
67
68
69
70
        public void Suppress([NotNull] string code)
        {
            if (!suppressAllTheThings)
                suppressions.Add(code);
        }

        public void Suppress([NotNull, ItemNotNull] IEnumerable<string> codes)
71
        {
72
73
74
75
76
77
78
79
80
81
82
83
84
85
            if (!suppressAllTheThings)
                suppressions.UnionWith(codes);
        }

        public void SuppressAll()
        {
            suppressAllTheThings = true;
            suppressions.Clear();
        }

        public void SuppressNone()
        {
            suppressAllTheThings = false;
            suppressions.Clear();
86
87
        }

88
89
        public void Handle([NotNull] Diagnostic diag)
        {
90
91
92
93
94
            if (WarningsAsErrors && diag.Severity == Severity.Warning)
            {
                diag = diag.WithSeverity(Severity.Error);
            }

95
            diagnostics.Add(diag);
96

97
            if (diag.Severity == Severity.Error && ErrorCount >= MaxErrorCount)
98
            {
99
                TooManyErrors?.Invoke(this, EventArgs.Empty);
100
101
            }

102
            if (IsSuppressed(diag))
103
104
105
106
            {
                suppressedDiagnostics.Add(diag);
            }
            else
107
            {
108
109
                OutputWriter.WriteLine(Formatter.Format(diag));
            }
110
        }
111
112
113
114
115
116

        private bool IsSuppressed([NotNull] Diagnostic diag)
        {
            if (diag.Severity >= Severity.Error)
                return false;

117
118
119
            if (SuppressNoisyWarnings && diag.Severity == Severity.Warning && diag.Noisy)
                return true;

120
121
            return suppressAllTheThings || suppressions.Contains(diag.Code);
        }
122
123
    }
}