-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathDiagnosticClassifier.cs
More file actions
96 lines (87 loc) · 3.46 KB
/
DiagnosticClassifier.cs
File metadata and controls
96 lines (87 loc) · 3.46 KB
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
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Semmle.Util;
namespace Semmle.Autobuild.Shared
{
/// <summary>
/// Direct results result from the successful application of a <see cref="DiagnosticRule" />,
/// which can later be converted to a corresponding <see cref="DiagnosticMessage" />.
/// </summary>
public interface IDiagnosticsResult
{
/// <summary>
/// Produces a <see cref="DiagnosticMessage" /> corresponding to this result.
/// </summary>
/// <param name="builder">
/// The autobuilder to use for constructing the base <see cref="DiagnosticMessage" />.
/// </param>
/// <param name="severity">
/// An optional severity value which overrides the default severity of the diagnostic.
/// </param>
/// <returns>The <see cref="DiagnosticMessage" /> corresponding to this result.</returns>
DiagnosticMessage ToDiagnosticMessage<T>(Autobuilder<T> builder, DiagnosticMessage.TspSeverity? severity = null) where T : AutobuildOptionsShared;
}
public class DiagnosticRule
{
/// <summary>
/// The pattern against which this rule matches build output.
/// </summary>
public Regex Pattern { get; }
/// <summary>
/// Constructs a diagnostic rule for the given <paramref name="pattern" />.
/// </summary>
/// <param name="pattern"></param>
public DiagnosticRule(Regex pattern)
{
this.Pattern = pattern;
}
/// <summary>
/// Constructs a diagnostic rule for the given regular expression <paramref name="pattern" />.
/// </summary>
/// <param name="pattern"></param>
public DiagnosticRule(string pattern)
{
this.Pattern = new Regex(pattern, RegexOptions.Compiled);
}
/// <summary>
/// Used by a <see cref="DiagnosticClassifier" /> <paramref name="classifier" /> to
/// signal that the rule has matched some build output with <paramref name="match" />.
/// </summary>
/// <param name="classifier">The classifier which is firing the rule.</param>
/// <param name="match">The <see cref="Match" /> that resulted from applying the rule.</param>
public virtual void Fire(DiagnosticClassifier classifier, Match match) { }
}
public class DiagnosticClassifier
{
private readonly List<DiagnosticRule> rules;
public List<IDiagnosticsResult> Results { get; }
public DiagnosticClassifier()
{
this.rules = new List<DiagnosticRule>();
this.Results = new List<IDiagnosticsResult>();
}
/// <summary>
/// Adds <paramref name="rule" /> to this classifier.
/// </summary>
/// <param name="rule">The rule to add.</param>
protected void AddRule(DiagnosticRule rule)
{
this.rules.Add(rule);
}
/// <summary>
/// Applies all of this classifier's rules to <paramref name="line" /> to see which match.
/// </summary>
/// <param name="line">The line to which the rules should be applied to.</param>
public void ClassifyLine(string line)
{
this.rules.ForEach(rule =>
{
var match = rule.Pattern.Match(line);
if (match.Success)
{
rule.Fire(this, match);
}
});
}
}
}