8
8
9
9
namespace Elastic . Markdown . Diagnostics ;
10
10
11
+ public enum Severity
12
+ {
13
+ Error ,
14
+ Warning ,
15
+ Hint
16
+ }
17
+
18
+ public readonly record struct Diagnostic
19
+ {
20
+ public Severity Severity { get ; init ; }
21
+ public int ? Line { get ; init ; }
22
+ public int ? Column { get ; init ; }
23
+ public int ? Length { get ; init ; }
24
+ public string File { get ; init ; }
25
+ public string Message { get ; init ; }
26
+ }
27
+
11
28
public sealed class DiagnosticsChannel : IDisposable
12
29
{
13
30
private readonly Channel < Diagnostic > _channel ;
@@ -18,7 +35,11 @@ public sealed class DiagnosticsChannel : IDisposable
18
35
19
36
public DiagnosticsChannel ( )
20
37
{
21
- var options = new UnboundedChannelOptions { SingleReader = true , SingleWriter = false } ;
38
+ var options = new UnboundedChannelOptions
39
+ {
40
+ SingleReader = true ,
41
+ SingleWriter = false
42
+ } ;
22
43
_ctxSource = new CancellationTokenSource ( ) ;
23
44
_channel = Channel . CreateUnbounded < Diagnostic > ( options ) ;
24
45
}
@@ -43,18 +64,6 @@ public void Write(Diagnostic diagnostic)
43
64
public void Dispose ( ) => _ctxSource . Dispose ( ) ;
44
65
}
45
66
46
- public enum Severity { Error , Warning }
47
-
48
- public readonly record struct Diagnostic
49
- {
50
- public Severity Severity { get ; init ; }
51
- public int ? Line { get ; init ; }
52
- public int ? Column { get ; init ; }
53
- public int ? Length { get ; init ; }
54
- public string File { get ; init ; }
55
- public string Message { get ; init ; }
56
- }
57
-
58
67
public interface IDiagnosticsOutput
59
68
{
60
69
void Write ( Diagnostic diagnostic ) ;
@@ -67,13 +76,17 @@ public class DiagnosticsCollector(IReadOnlyCollection<IDiagnosticsOutput> output
67
76
68
77
private int _errors ;
69
78
private int _warnings ;
79
+ private int _hints ;
70
80
public int Warnings => _warnings ;
71
81
public int Errors => _errors ;
82
+ public int Hints => _hints ;
72
83
73
84
private Task ? _started ;
74
85
75
86
public HashSet < string > OffendingFiles { get ; } = [ ] ;
76
87
88
+ public HashSet < string > InUseSubstitutionKeys { get ; } = [ ] ;
89
+
77
90
public ConcurrentBag < string > CrossLinks { get ; } = [ ] ;
78
91
79
92
public Task StartAsync ( Cancel cancellationToken )
@@ -119,6 +132,8 @@ private void IncrementSeverityCount(Diagnostic item)
119
132
_ = Interlocked . Increment ( ref _errors ) ;
120
133
else if ( item . Severity == Severity . Warning )
121
134
_ = Interlocked . Increment ( ref _warnings ) ;
135
+ else if ( item . Severity == Severity . Hint )
136
+ _ = Interlocked . Increment ( ref _hints ) ;
122
137
}
123
138
124
139
protected virtual void HandleItem ( Diagnostic diagnostic ) { }
@@ -132,35 +147,33 @@ public virtual async Task StopAsync(Cancel cancellationToken)
132
147
133
148
public void EmitCrossLink ( string link ) => CrossLinks . Add ( link ) ;
134
149
135
- public void EmitError ( string file , string message , Exception ? e = null )
136
- {
137
- var d = new Diagnostic
150
+ private void Emit ( Severity severity , string file , string message ) =>
151
+ Channel . Write ( new Diagnostic
138
152
{
139
- Severity = Severity . Error ,
153
+ Severity = severity ,
140
154
File = file ,
141
155
Message = message
142
- + ( e != null ? Environment . NewLine + e : string . Empty )
143
- + ( e ? . InnerException != null ? Environment . NewLine + e . InnerException : string . Empty ) ,
156
+ } ) ;
144
157
145
- } ;
146
- Channel . Write ( d ) ;
147
- }
148
-
149
- public void EmitWarning ( string file , string message )
158
+ public void EmitError ( string file , string message , Exception ? e = null )
150
159
{
151
- var d = new Diagnostic
152
- {
153
- Severity = Severity . Warning ,
154
- File = file ,
155
- Message = message ,
156
- } ;
157
- Channel . Write ( d ) ;
160
+ message = message
161
+ + ( e != null ? Environment . NewLine + e : string . Empty )
162
+ + ( e ? . InnerException != null ? Environment . NewLine + e . InnerException : string . Empty ) ;
163
+ Emit ( Severity . Error , file , message ) ;
158
164
}
159
165
166
+ public void EmitWarning ( string file , string message ) => Emit ( Severity . Warning , file , message ) ;
167
+
168
+ public void EmitHint ( string file , string message ) => Emit ( Severity . Hint , file , message ) ;
169
+
160
170
public async ValueTask DisposeAsync ( )
161
171
{
162
172
Channel . TryComplete ( ) ;
163
173
await StopAsync ( CancellationToken . None ) ;
164
174
GC . SuppressFinalize ( this ) ;
165
175
}
176
+
177
+ public void CollectUsedSubstitutionKey ( ReadOnlySpan < char > key ) =>
178
+ _ = InUseSubstitutionKeys . Add ( key . ToString ( ) ) ;
166
179
}
0 commit comments